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 { }