Sort the top level validator class to handle most specific classes first.
[JSR 303 TCK Result] 87 of 257 (33.85%) Pass with 39 Failures and 14 Errors.
Review at http://gwt-code-reviews.appspot.com/1346804
Review by: rchandia@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9708 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/validation/rebind/Util.java b/user/src/com/google/gwt/validation/rebind/Util.java
index b0616ab..0d140fc 100644
--- a/user/src/com/google/gwt/validation/rebind/Util.java
+++ b/user/src/com/google/gwt/validation/rebind/Util.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
@@ -22,10 +22,10 @@
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet;
import com.google.gwt.thirdparty.guava.common.collect.Iterables;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
-import com.google.gwt.thirdparty.guava.common.collect.Ordering;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -37,14 +37,14 @@
/**
* Creates a Predicate that returns false if source contains an associated
* class that is a super type of the class associated with the tested T.
- *
+ *
* @param <T> the type to test
- * @param source the Set of <T> to look for class matches.
+ * @param source the set of <T> to look for class matches.
* @param toClass Function from T to Class
* @return newly create predicate.
*/
- static <T> Predicate<T> createMostSpecificMatchPredicate(final Set<T> source,
- final Function<T, Class<?>> toClass) {
+ static <T> Predicate<T> createMostSpecificMatchPredicate(
+ final Iterable<T> source, final Function<T, Class<?>> toClass) {
return new Predicate<T>() {
public boolean apply(T input) {
@@ -62,7 +62,7 @@
/**
* Selects first only the classes that are assignable from the target, and
* then returns the most specific matching classes.
- *
+ *
* @param target the Class to match
* @param availableClasses classes to search
* @return Set of only the most specific classes that match the target.
@@ -91,16 +91,24 @@
*/
static <T> ImmutableList<T> sortMostSpecificFirst(Iterable<T> classes,
Function<T, Class<?>> toClass) {
- Set<T> working = Sets.newHashSet(classes);
+ List<T> working = Lists.newArrayList();
+ // strip duplicates
+ for (T t : classes) {
+ if (!working.contains(t)) {
+ working.add(t);
+ }
+ }
List<T> sorted = Lists.newArrayList();
- Predicate<T> mostSpecific = createMostSpecificMatchPredicate(working, toClass);
+ Predicate<T> mostSpecific = createMostSpecificMatchPredicate(working,
+ toClass);
boolean changed = false;
do {
changed = false;
- for (T t : Ordering.usingToString().sortedCopy(working)) {
+ for (Iterator<T> iterator = working.iterator(); iterator.hasNext();) {
+ T t = iterator.next();
if (mostSpecific.apply(t)) {
sorted.add(t);
- working.remove(t);
+ iterator.remove();
changed = true;
}
}
diff --git a/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
index 33e75fe..ff00dee 100644
--- a/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
@@ -20,6 +20,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
@@ -43,10 +44,9 @@
/**
* The beans to validate in source declaration order.
*/
- private final List<BeanHelper> beansToValidate = Lists.newArrayList();
+ private final ImmutableList<BeanHelper> beansToValidate;
private final GwtValidation gwtValidation;
-
public ValidatorCreator(JClassType validatorType, //
GwtValidation gwtValidation, //
TreeLogger logger, //
@@ -54,11 +54,12 @@
super(context, logger, validatorType);
this.gwtValidation = gwtValidation;
-
+ List<BeanHelper> temp = Lists.newArrayList();
for (Class<?> clazz : gwtValidation.value()) {
BeanHelper helper = createBeanHelper(clazz);
- beansToValidate.add(helper);
+ temp.add(helper);
}
+ beansToValidate = Util.sortMostSpecificFirst(temp, BeanHelper.TO_CLAZZ);
}
@Override
diff --git a/user/test/com/google/gwt/validation/rebind/UtilTest.java b/user/test/com/google/gwt/validation/rebind/UtilTest.java
index f55f07c..1e42976 100644
--- a/user/test/com/google/gwt/validation/rebind/UtilTest.java
+++ b/user/test/com/google/gwt/validation/rebind/UtilTest.java
@@ -57,46 +57,56 @@
private static void assertContentsInOrder(List<Class<?>> actual,
Class<?>... classes) {
- assertEquals(ImmutableList.copyOf(classes), actual);
+ assertEquals(ImmutableList.copyOf(classes), ImmutableList.copyOf(actual));
}
- private static ImmutableSet<Class<?>> of(Class<?>... classes) {
+ private static ImmutableList<Class<?>> list(Class<?>... classes) {
+ return ImmutableList.copyOf(classes);
+ }
+
+ private static ImmutableSet<Class<?>> set(Class<?>... classes) {
return ImmutableSet.copyOf(classes);
}
public void testBestMatches_Bobby2() {
Set<Class<?>> actual = findBestMatches(Bobby2.class,
- of(Alice.class, Bob.class, Bobby.class));
+ set(Alice.class, Bob.class, Bobby.class));
assertEquals(1, actual.size());
assertEquals(Bobby.class, Iterables.get(actual, 0));
}
public void testBestMatches_none() {
- Set<Class<?>> actual = Util.findBestMatches(Bob.class, of(Alice.class));
+ Set<Class<?>> actual = Util.findBestMatches(Bob.class, set(Alice.class));
assertEquals(0, actual.size());
}
public void testBestMatches_one() {
Set<Class<?>> actual = findBestMatches(Bob.class,
- of(Alice.class, Bob.class));
+ set(Alice.class, Bob.class));
assertEquals(1, actual.size());
assertEquals(Bob.class, Iterables.get(actual, 0));
}
public void testBestMatches_two() {
- Set<Class<?>> actual = findBestMatches(Chuck.class, of(C1.class, C2.class));
+ Set<Class<?>> actual = findBestMatches(Chuck.class, set(C1.class, C2.class));
assertEquals(2, actual.size());
}
public void testSortMostSpecificFirst_chuck() {
List<Class<?>> actual = Util.sortMostSpecificFirst(
- of(C2.class, C1.class, Chuck.class), classIdentity);
- assertContentsInOrder(actual, Chuck.class, C1.class, C2.class);
+ list(C2.class, C1.class, Chuck.class), classIdentity);
+ assertContentsInOrder(actual, Chuck.class, C2.class, C1.class);
+ }
+
+ public void testSortMostSpecificFirst_double() {
+ List<Class<?>> actual = Util.sortMostSpecificFirst(
+ list(Alice.class, Alice.class, Bob.class), classIdentity);
+ assertContentsInOrder(actual, Alice.class, Bob.class);
}
public void testSortMostSpecificFirst_one() {
- List<Class<?>> actual = Util.sortMostSpecificFirst(of(Alice.class),
+ List<Class<?>> actual = Util.sortMostSpecificFirst(list(Alice.class),
classIdentity);
assertContentsInOrder(actual, Alice.class);
}
diff --git a/user/test/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/TckTestValidatorFactory.java b/user/test/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/TckTestValidatorFactory.java
index a1db13b..38aaa79 100644
--- a/user/test/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/TckTestValidatorFactory.java
+++ b/user/test/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/TckTestValidatorFactory.java
@@ -31,8 +31,7 @@
* Marker Interface for {@link GWT#create(Class)}.
*/
@GwtValidation(value = {
- // German and French must be listed before the Address Super class
- GermanAddress.class, FrenchAddress.class, Address.class, Friend.class,
+ Address.class, FrenchAddress.class, Friend.class, GermanAddress.class,
Shoe.class
// TODO(nchalko) handle ConstraintDefinitionException
// ConstraintCompositionGwtTest.DummyEntityWithZipCode.class
diff --git a/user/test/org/hibernate/jsr303/tck/tests/constraints/validatorresolution/TckTestValidatorFactory.java b/user/test/org/hibernate/jsr303/tck/tests/constraints/validatorresolution/TckTestValidatorFactory.java
index 2475214..85e7c8b 100644
--- a/user/test/org/hibernate/jsr303/tck/tests/constraints/validatorresolution/TckTestValidatorFactory.java
+++ b/user/test/org/hibernate/jsr303/tck/tests/constraints/validatorresolution/TckTestValidatorFactory.java
@@ -36,7 +36,7 @@
* Marker Interface for {@link GWT#create(Class)}.
*/
@GwtValidation(value = {
- Bar.class, CustomInterfaceImpl.class, CustomClass.class, Foo.class,
+ Bar.class, CustomClass.class, CustomInterfaceImpl.class, Foo.class,
MinMax.class, SubClassAHolder.class, SubClassBHolder.class, Suburb.class})
public static interface GwtValidator extends Validator {
}
diff --git a/user/test/org/hibernate/jsr303/tck/tests/validation/TckTestValidatorFactory.java b/user/test/org/hibernate/jsr303/tck/tests/validation/TckTestValidatorFactory.java
index f3e0055..12cb1b7 100644
--- a/user/test/org/hibernate/jsr303/tck/tests/validation/TckTestValidatorFactory.java
+++ b/user/test/org/hibernate/jsr303/tck/tests/validation/TckTestValidatorFactory.java
@@ -35,10 +35,9 @@
* Marker Interface for {@link GWT#create(Class)}.
*/
@GwtValidation(value = {
- // Actor must be after its subclasses
- ActorDB.class, ActorArrayBased.class, ActorListBased.class, Actor.class,
- Address.class, BadlyBehavedEntity.class, Car.class,
- Customer.class, Engine.class, Order.class, VerySpecialClass.class})
+ ActorArrayBased.class, ActorDB.class, ActorListBased.class, Actor.class,
+ Address.class, BadlyBehavedEntity.class, Car.class, Customer.class,
+ Engine.class, Order.class, VerySpecialClass.class})
public static interface GwtValidator extends Validator {
}
diff --git a/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/TckTestValidatorFactory.java b/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/TckTestValidatorFactory.java
index 1f6e2ca..4ce7357 100644
--- a/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/TckTestValidatorFactory.java
+++ b/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/TckTestValidatorFactory.java
@@ -31,10 +31,9 @@
* Marker Interface for {@link GWT#create(Class)}.
*/
@GwtValidation(value = {
- AnimalCaretaker.class, Elephant.class, Condor.class, GameReserve.class,
- Parent.class,
- MultiCage.class, MultiCage.class, SingleCage.class, Zebra.class,
- Zoo.class})
+ AnimalCaretaker.class, Condor.class, Elephant.class, GameReserve.class,
+ MultiCage.class, MultiCage.class, Parent.class, SingleCage.class,
+ Zebra.class, Zoo.class})
public static interface GwtValidator extends Validator {
}