GWT validation refactoring; no user-visible changes.

Do a dependency-injection refactoring so that calls to get the threadlocal are
only in two places (in the two generators).

Review at http://gwt-code-reviews.appspot.com/1806804

Review by: nchalko@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11210 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/validation/rebind/AbstractCreator.java b/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
index 6736bdb..82f1eed 100644
--- a/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
@@ -36,18 +36,20 @@
  */
 public abstract class AbstractCreator extends AbstractSourceCreator {
 
-  protected final GeneratorContext context;
+  final GeneratorContext context;
 
-  protected final TreeLogger logger;
+  final TreeLogger logger;
 
-  protected final JClassType validatorType;
+  final JClassType validatorType;
 
-  public AbstractCreator(GeneratorContext context, TreeLogger logger,
-      JClassType validatorType) {
-    super();
+  final BeanHelperCache cache;
+
+  AbstractCreator(GeneratorContext context, TreeLogger logger,
+      JClassType validatorType, BeanHelperCache cache) {
     this.context = context;
     this.logger = branch(logger, "Creating " + validatorType);
     this.validatorType = validatorType;
+    this.cache = cache;
   }
 
   public final String create() throws UnableToCompleteException {
@@ -70,18 +72,17 @@
 
   protected BeanHelper createBeanHelper(Class<?> clazz)
       throws UnableToCompleteException {
-    return BeanHelperCache.getForThread().createHelper(clazz, logger, context);
+    return cache.createHelper(clazz, logger, context);
   }
 
   protected BeanHelper createBeanHelper(JClassType jType)
       throws UnableToCompleteException {
-    return BeanHelperCache.getForThread().createHelper(jType, logger, context);
+    return cache.createHelper(jType, logger, context);
   }
 
   protected final String getPackage() {
     JPackage serviceIntfPkg = validatorType.getPackage();
-    String packageName = serviceIntfPkg == null ? "" : serviceIntfPkg.getName();
-    return packageName;
+    return serviceIntfPkg == null ? "" : serviceIntfPkg.getName();
   }
 
   protected String getSimpleName() {
@@ -110,8 +111,6 @@
     ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(
         packageName, simpleName);
     compose(composerFactory);
-    SourceWriter sourceWriter = composerFactory.createSourceWriter(ctx,
-        printWriter);
-    return sourceWriter;
+    return composerFactory.createSourceWriter(ctx, printWriter);
   }
 }
\ No newline at end of file
diff --git a/user/src/com/google/gwt/validation/rebind/BeanHelperCache.java b/user/src/com/google/gwt/validation/rebind/BeanHelperCache.java
index aa6f558..961cd16 100644
--- a/user/src/com/google/gwt/validation/rebind/BeanHelperCache.java
+++ b/user/src/com/google/gwt/validation/rebind/BeanHelperCache.java
@@ -54,17 +54,21 @@
   };
 
   /**
-   * Returns the cache for the current thread.
-   * (Public for testing.)
+   * Returns the cache for the current thread. (This is a hack because we have two generators
+   * that need to share state.)
    */
-  public static BeanHelperCache getForThread() {
+  static BeanHelperCache getForThread() {
     return threadLocal.get();
   }
 
   private final Map<JClassType, BeanHelper> cache;
   private final Validator serverSideValidator;
 
-  private BeanHelperCache() {
+  /**
+   * Creates a cache. There should be one cache per compiler run.
+   * (public for tests.)
+   */
+  public BeanHelperCache() {
     cache = new HashMap<JClassType, BeanHelper>();
     serverSideValidator = Validation.buildDefaultValidatorFactory().getValidator();
   }
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
index ba93579..e82f8ec 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
@@ -343,8 +343,8 @@
 
   public GwtSpecificValidatorCreator(JClassType validatorType,
       JClassType beanType, BeanHelper beanHelper, TreeLogger logger,
-      GeneratorContext context) {
-    super(context, logger, validatorType);
+      GeneratorContext context, BeanHelperCache cache) {
+    super(context, logger, validatorType, cache);
     this.beanType = beanType;
     this.beanHelper = beanHelper;
   }
@@ -1932,7 +1932,7 @@
   private void writeValidatorCall(SourceWriter sw, Class<?> type, Stage stage,
       PropertyDescriptor p, boolean expandDefaultGroupSequence, String groupsVarName)
       throws UnableToCompleteException {
-    if (BeanHelperCache.getForThread().isClassConstrained(type) && !isIterableOrMap(type)) {
+    if (cache.isClassConstrained(type) && !isIterableOrMap(type)) {
       BeanHelper helper = createBeanHelper(type);
       beansToValidate.add(helper);
       switch (stage) {
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
index a833069..d30a4b0 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
@@ -34,6 +34,18 @@
  */
 public final class GwtSpecificValidatorGenerator extends Generator {
 
+  private final BeanHelperCache cache;
+
+  // called by compiler via reflection
+  public GwtSpecificValidatorGenerator() {
+    this.cache = BeanHelperCache.getForThread();
+  }
+
+  // called by tests
+  public GwtSpecificValidatorGenerator(BeanHelperCache cache) {
+    this.cache = cache;
+  }
+
   @Override
   public String generate(TreeLogger logger, GeneratorContext context,
       String typeName) throws UnableToCompleteException {
@@ -51,7 +63,7 @@
     JClassType gwtSpecificInterface = getGwtSpecificValidator(logger, validator);
     JClassType beanType = getBeanType(logger, validator, gwtSpecificInterface);
 
-    BeanHelper beanHelper = BeanHelperCache.getForThread().createHelper(beanType, logger, context);
+    BeanHelper beanHelper = cache.createHelper(beanType, logger, context);
 
     if (beanHelper == null) {
       logger.log(TreeLogger.ERROR, "Unable to create BeanHelper for " + beanType
@@ -61,7 +73,7 @@
     }
 
     AbstractCreator creator = new GwtSpecificValidatorCreator(validatorType,
-        beanType, beanHelper, logger, context);
+        beanType, beanHelper, logger, context, cache);
     return creator.create();
   }
 
diff --git a/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
index 2b7ab9d..68a6fc5 100644
--- a/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
@@ -59,8 +59,9 @@
   public ValidatorCreator(JClassType validatorType, //
       GwtValidation gwtValidation, //
       TreeLogger logger, //
-      GeneratorContext context) throws UnableToCompleteException {
-    super(context, logger, validatorType);
+      GeneratorContext context,
+      BeanHelperCache cache) throws UnableToCompleteException {
+    super(context, logger, validatorType, cache);
     this.gwtValidation = gwtValidation;
 
     List<BeanHelper> temp = Lists.newArrayList();
@@ -242,7 +243,7 @@
     sw.println("checkNotNull(groups, \"groups\");");
     sw.println("checkGroups(groups);");
 
-    for (BeanHelper bean : BeanHelperCache.getForThread().getAllBeans()) {
+    for (BeanHelper bean : cache.getAllBeans()) {
       writeGwtValidate(sw, bean);
     }
 
diff --git a/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java b/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java
index 41e97c7..f0567e8 100644
--- a/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java
+++ b/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java
@@ -34,6 +34,18 @@
  */
 public final class ValidatorGenerator extends Generator {
 
+  private final BeanHelperCache cache;
+
+  // called by the compiler via reflection
+  public ValidatorGenerator() {
+    this.cache = BeanHelperCache.getForThread();
+  }
+
+  // called from tests
+  public ValidatorGenerator(BeanHelperCache cache) {
+    this.cache = cache;
+  }
+
   @Override
   public String generate(TreeLogger logger, GeneratorContext context,
       String typeName) throws UnableToCompleteException {
@@ -75,7 +87,7 @@
     AbstractCreator creator = new ValidatorCreator(validatorType,
         gwtValidation,
         validatorLogger,
-        context);
+        context, cache);
     return creator.create();
   }
 }
diff --git a/user/test/org/hibernate/jsr303/tck/util/TckCompileTestCase.java b/user/test/org/hibernate/jsr303/tck/util/TckCompileTestCase.java
index 04a17e1..4f1547e 100644
--- a/user/test/org/hibernate/jsr303/tck/util/TckCompileTestCase.java
+++ b/user/test/org/hibernate/jsr303/tck/util/TckCompileTestCase.java
@@ -39,6 +39,7 @@
  */
 public abstract class TckCompileTestCase extends TestCase {
 
+  private BeanHelperCache cache;
   private StandardGeneratorContext context;
   private TreeLogger failOnErrorLogger;
 
@@ -46,13 +47,14 @@
       Class<? extends Validator> validatorClass, Class<?> beanType,
       Class<? extends ValidationException> expectedException,
       String expectedMessage) throws UnableToCompleteException {
-    ValidatorGenerator generator = new ValidatorGenerator();
+    ValidatorGenerator generator = new ValidatorGenerator(cache);
     generator.generate(failOnErrorLogger, context,
         validatorClass.getCanonicalName());
     context.finish(failOnErrorLogger);
 
     // Now create the validator that is going to fail
-    GwtSpecificValidatorGenerator specificGenerator = new GwtSpecificValidatorGenerator();
+    GwtSpecificValidatorGenerator specificGenerator =
+        new GwtSpecificValidatorGenerator(cache);
     String beanHelperName = createBeanHelper(beanType);
     assertUnableToComplete(expectedException, expectedMessage,
         specificGenerator, beanHelperName);
@@ -62,7 +64,7 @@
       Class<? extends Validator> validatorClass,
       Class<? extends ValidationException> expectedException,
       String expectedMessage) {
-    ValidatorGenerator generator = new ValidatorGenerator();
+    ValidatorGenerator generator = new ValidatorGenerator(cache);
     assertUnableToComplete(expectedException, expectedMessage, generator,
         validatorClass.getCanonicalName());
   }
@@ -70,17 +72,11 @@
   @Override
   protected void setUp() throws Exception {
     super.setUp();
-    BeanHelperCache.getForThread().clear();
+    cache = new BeanHelperCache();
     failOnErrorLogger = createFailOnErrorLogger();
     context = createGeneratorContext(getTckTestModuleName(), failOnErrorLogger);
   }
 
-  @Override
-  protected void tearDown() throws Exception {
-    BeanHelperCache.getForThread().clear();
-    super.tearDown();
-  }
-
   private void assertUnableToComplete(
       Class<? extends ValidationException> expectedException,
       String expectedMessage, Generator generator, final String typeName) {
@@ -98,7 +94,7 @@
 
   private String createBeanHelper(Class<?> beanType)
       throws UnableToCompleteException {
-    return BeanHelperCache.getForThread().createHelper(beanType, failOnErrorLogger, context)
+    return cache.createHelper(beanType, failOnErrorLogger, context)
         .getFullyQualifiedValidatorName();
   }