Add baseInterface support to UiBinder.

Review by: rjrjr@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10199 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java b/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java
index b8175e9..ee3fa88 100644
--- a/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java
+++ b/user/src/com/google/gwt/uibinder/rebind/UiBinderGenerator.java
@@ -158,7 +158,7 @@
 
     MortalLogger logger = new MortalLogger(treeLogger);
     String templatePath = deduceTemplateFile(logger, interfaceType);
-    MessagesWriter messages = new MessagesWriter(BINDER_URI, logger,
+    MessagesWriter messages = new MessagesWriter(oracle, BINDER_URI, logger,
         templatePath, interfaceType.getPackage().getName(), implName);
 
     boolean useLazyWidgetBuilders = useLazyWidgetBuilders(logger, propertyOracle);
diff --git a/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java b/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java
index 1ddab62..2b9c122 100644
--- a/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java
+++ b/user/src/com/google/gwt/uibinder/rebind/messages/MessagesWriter.java
@@ -16,6 +16,9 @@
 package com.google.gwt.uibinder.rebind.messages;
 
 import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.i18n.client.Messages;
 import com.google.gwt.uibinder.rebind.IndentedWriter;
 import com.google.gwt.uibinder.rebind.MortalLogger;
 import com.google.gwt.uibinder.rebind.UiBinderWriter;
@@ -49,6 +52,7 @@
   private final List<MessageWriter> messages = new ArrayList<MessageWriter>();
   private final String generatedFrom;
 
+  private String baseInterface;
   private String defaultLocale;
   private String messagesPrefix;
   private String generateKeys;
@@ -57,7 +61,9 @@
   private Map<XMLElement, Collection<AttributeMessage>> elemToAttributeMessages =
       new HashMap<XMLElement, Collection<AttributeMessage>>();
 
-  public MessagesWriter(String nameSpaceUri, MortalLogger mortalLogger, String generatedFrom,
+  private TypeOracle oracle;
+
+  public MessagesWriter(TypeOracle oracle, String nameSpaceUri, MortalLogger mortalLogger, String generatedFrom,
       String packageName, String uiBinderImplClassName) {
     this.messagesNamespaceURI = nameSpaceUri;
     this.generatedFrom = generatedFrom;
@@ -67,6 +73,9 @@
     this.messagesClassName = uiBinderImplClassName.replaceAll("_", "") + "GenMessages";
 
     this.logger = mortalLogger;
+    this.oracle = oracle;
+
+    baseInterface = Messages.class.getCanonicalName();
   }
 
   /**
@@ -150,11 +159,31 @@
   /**
    * Expected to be called with the root element, to allow configuration from
    * various messages related attributes.
+   * 
+   * @throws UnableToCompleteException 
    */
-  public void findMessagesConfig(XMLElement elem) {
+  public void findMessagesConfig(XMLElement elem) throws UnableToCompleteException {
     String prefix = elem.lookupPrefix(getMessagesUri());
     if (prefix != null) {
       messagesPrefix = prefix;
+      String baseInterfaceAttr = elem.consumeRawAttribute(getMessagesPrefix() + ":baseInterface");
+      if (baseInterfaceAttr != null) {
+        JClassType baseInterfaceType = oracle.findType(baseInterfaceAttr);
+        if (baseInterfaceType == null) {
+          logger.die(elem, "Could not find class %s", baseInterfaceAttr);
+        }
+        if (baseInterfaceType.isInterface() == null) {
+          logger.die(elem, "%s must be an interface", baseInterfaceAttr);
+        }
+        JClassType msgType = oracle.findType(Messages.class.getCanonicalName());
+        if (msgType == null) {
+          throw new RuntimeException("Internal Error: Messages interface not found");
+        }
+        if (!msgType.isAssignableFrom(baseInterfaceType)) {
+          logger.die(elem, "Interface %s must extend Messages", baseInterfaceAttr);
+        }
+        baseInterface = baseInterfaceAttr;
+      }
       defaultLocale = consumeMessageAttribute("defaultLocale", elem);
       generateKeys = consumeMessageAttribute("generateKeys", elem);
       generate =
@@ -240,13 +269,12 @@
     }
 
     // Imports.
-    writer.write("import com.google.gwt.i18n.client.Messages;");
     writer.write("import static com.google.gwt.i18n.client.LocalizableResource.*;");
     writer.newline();
 
     // Open interface.
     genInterfaceAnnotations(writer);
-    writer.write("public interface %s extends Messages {", getMessagesClassName());
+    writer.write("public interface %s extends %s {", getMessagesClassName(), baseInterface);
     writer.newline();
     writer.indent();
 
diff --git a/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java b/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
index 8e6f83a..6db69b9 100644
--- a/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
+++ b/user/test/com/google/gwt/uibinder/elementparsers/ElementParserTester.java
@@ -110,7 +110,7 @@
 
     fieldManager = new FieldManager(types, logger, false);
     JClassType baseType = types.findType("my.Ui.BaseClass");
-    MessagesWriter messages = new MessagesWriter(BINDER_URI, logger,
+    MessagesWriter messages = new MessagesWriter(types, BINDER_URI, logger,
         templatePath, baseType.getPackage().getName(), implName);
 
     writer = new MockUiBinderWriter(baseType, implName, templatePath, types,
diff --git a/user/test/com/google/gwt/uibinder/test/client/MyMessages.java b/user/test/com/google/gwt/uibinder/test/client/MyMessages.java
new file mode 100644
index 0000000..e5ef785
--- /dev/null
+++ b/user/test/com/google/gwt/uibinder/test/client/MyMessages.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2011 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.test.client;
+
+import com.google.gwt.i18n.client.Messages;
+import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale;
+
+/**
+ * Base messages to prove we can override the default.
+ */
+@DefaultLocale("en_US")
+public interface MyMessages extends Messages {
+}
diff --git a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
index 4dd074c..6402452 100644
--- a/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
+++ b/user/test/com/google/gwt/uibinder/test/client/WidgetBasedUi.ui.xml
@@ -54,6 +54,7 @@
   xmlns:legacyValuesForBeans='urn:with:com.google.gwt.uibinder.test.client.WidgetBasedUi.FakeBundle2'
   xmlns:legacyValuesForHtml='urn:with:com.google.gwt.uibinder.test.client.WidgetBasedUi.FakeBundle3'
 
+  ui:baseInterface="com.google.gwt.uibinder.test.client.MyMessages"
   ui:defaultLocale="en_US"
   ui:generateKeys="com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator"
   ui:generateFormat="com.google.gwt.i18n.rebind.format.PropertiesFormat"