HACK: compiler clears out pinned i18n static data to free memory.
TODO: make i18n.rebind not pin static state.

Review by: jat

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5171 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 90a10c0..5244774 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -369,6 +369,14 @@
     if (!options.isCompilationStateRetained()) {
       module.clear();
     }
+    try {
+      // HACK: Make i18n free its internal static state.
+      Class<?> clazz = Class.forName(
+          "com.google.gwt.i18n.rebind.ClearStaticData", false,
+          Thread.currentThread().getContextClassLoader());
+      clazz.getDeclaredMethod("clear").invoke(null);
+    } catch (Throwable e) {
+    }
 
     // Check for compilation problems. We don't log here because any problems
     // found here will have already been logged by AbstractCompiler.
diff --git a/user/src/com/google/gwt/i18n/rebind/ClearStaticData.java b/user/src/com/google/gwt/i18n/rebind/ClearStaticData.java
new file mode 100644
index 0000000..1df9c25
--- /dev/null
+++ b/user/src/com/google/gwt/i18n/rebind/ClearStaticData.java
@@ -0,0 +1,28 @@
+/*

+ * Copyright 2009 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.i18n.rebind;

+

+/**

+ * HACK: Allows clearing accumulated static state.

+ * 

+ * TODO(jat): Make i18n.rebind not pin static state.

+ */

+public class ClearStaticData {

+  public static void clear() {

+    ResourceFactory.clearCache();

+    LocaleUtils.clear();

+  }

+}

diff --git a/user/src/com/google/gwt/i18n/rebind/LocaleUtils.java b/user/src/com/google/gwt/i18n/rebind/LocaleUtils.java
index eedb41c..d399cc1 100644
--- a/user/src/com/google/gwt/i18n/rebind/LocaleUtils.java
+++ b/user/src/com/google/gwt/i18n/rebind/LocaleUtils.java
@@ -32,7 +32,7 @@
 public class LocaleUtils {
   // TODO(jat): rewrite to avoid statics
 
-  private static GwtLocaleFactory factory = new GwtLocaleFactoryImpl();
+  private static final GwtLocaleFactoryImpl factory = new GwtLocaleFactoryImpl();
 
   /**
    * The token representing the locale property controlling Localization.
@@ -46,11 +46,19 @@
 
   private static GwtLocale compileLocale;
 
-  private static Set<GwtLocale> allLocales = new HashSet<GwtLocale>();
+  private static final Set<GwtLocale> allLocales = new HashSet<GwtLocale>();
 
-  private static Set<GwtLocale> allCompileLocales = new HashSet<GwtLocale>();
-  
-  private static Set<GwtLocale> runtimeLocales = new HashSet<GwtLocale>();
+  private static final Set<GwtLocale> allCompileLocales = new HashSet<GwtLocale>();
+
+  private static final Set<GwtLocale> runtimeLocales = new HashSet<GwtLocale>();
+
+  public static void clear() {
+    allCompileLocales.clear();
+    allLocales.clear();
+    compileLocale = null;
+    factory.clear();
+    runtimeLocales.clear();
+  }
 
   /**
    * Returns the set of all compile-time locales.
@@ -112,9 +120,9 @@
         return;
       }
       compileLocale = newCompileLocale;
-      allLocales = new HashSet<GwtLocale>();
-      allCompileLocales = new HashSet<GwtLocale>();
-      runtimeLocales = new HashSet<GwtLocale>();
+      allLocales.clear();
+      allCompileLocales.clear();
+      runtimeLocales.clear();
       String[] localeValues = propertyOracle.getPropertyValueSet(logger,
           PROP_LOCALE);
       String rtLocaleNames = propertyOracle.getPropertyValue(logger,
diff --git a/user/src/com/google/gwt/i18n/rebind/LocalizableGenerator.java b/user/src/com/google/gwt/i18n/rebind/LocalizableGenerator.java
index eb18c77..64ed8e0 100644
--- a/user/src/com/google/gwt/i18n/rebind/LocalizableGenerator.java
+++ b/user/src/com/google/gwt/i18n/rebind/LocalizableGenerator.java
@@ -94,13 +94,13 @@
     }
     return generate(logger, context, typeName, locale);
   }
-  
+
   public final String generate(TreeLogger logger, GeneratorContext context,
       String typeName, String localeName) throws UnableToCompleteException {
     // Clear cache if reset was done.
     TypeOracle typeOracle = context.getTypeOracle();
     if (lastReloadCount != typeOracle.getReloadCount()) {
-      ResourceFactory.clearCache();
+      ClearStaticData.clear();
       lastReloadCount = typeOracle.getReloadCount();
     }
 
diff --git a/user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java b/user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java
index 47b2a93..d67321d 100644
--- a/user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java
+++ b/user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java
@@ -68,6 +68,10 @@
   // one is used instead to preserved cached data structures.
   private Map<GwtLocaleImpl, GwtLocaleImpl> instanceCache = new HashMap<GwtLocaleImpl, GwtLocaleImpl>();
 
+  public void clear() {
+    instanceCache.clear();
+  }
+
   public GwtLocale fromComponents(String language, String script,
       String region, String variant) {
     if (language != null && language.length() == 0) {