Author: hlship
Date: Tue Jan 23 14:32:18 2007
New Revision: 499164
URL: http://svn.apache.org/viewvc?view=rev&rev=499164
Log:
Change inheritance search to consider the super-class of a primitive type to be
the corresponding wrapper type.
Modified:
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java
tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java
Modified:
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java?view=diff&rev=499164&r1=499163&r2=499164
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java
(original)
+++
tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/util/InheritanceSearch.java
Tue Jan 23 14:32:18 2007
@@ -12,153 +12,159 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.ioc.internal.util;
-
+package org.apache.tapestry.ioc.internal.util;
+
import static
org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newSet;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Set;
-
-/**
- * Used to search from a particular class up the inheritance hierarchy of
extended classes and
- * implemented interfaces.
- * <p>
- * The search starts with the initial class (provided in the constructor). It
progresses up the
- * inheritance chain, but skips java.lang.Object.
- * <p>
- * Once classes are exhausted, the inheritance hiearchy is searched. This is a
breadth-first search,
- * rooted in the interfaces implemented by the initial class at its super
classes.
- * <p>
- * Once all interfaces are exhausted, java.lang.Object is returned (it is
always returned last).
- * <p>
- * One minor tweak to normal inheritance rules. Normally, the parent class of
an <em>object</em>
- * array is java.lang.Object, which is odd because Foo[] is assignable to
Object[]. Thus, we tweak
- * the search so that the effective super class of Foo[] is Object[].
- * <p>
- * This class implements the [EMAIL PROTECTED] Iterable} interface, so it can
be used directly in a for loop:
- * <code>
- * for (Class search : new InheritanceSearch(startClass)) {
- * ...
- * }
- * </code>
- * <p>
- * This class is not threadsafe.
- *
- *
- */
-public class InheritanceSearch implements Iterator<Class>, Iterable<Class>
-{
- private Class _searchClass;
-
- private final Set<Class> _addedInterfaces = newSet();
-
- private final LinkedList<Class> _interfaceQueue = newLinkedList();
-
- private enum State {
- CLASS, INTERFACE, DONE;
- }
-
- private State _state;
-
- public InheritanceSearch(Class searchClass)
- {
- _searchClass = searchClass;
-
- queueInterfaces(searchClass);
-
- _state = searchClass == Object.class ? State.INTERFACE : State.CLASS;
- }
-
- private void queueInterfaces(Class searchClass)
- {
- for (Class intf : searchClass.getInterfaces())
- {
- if (_addedInterfaces.contains(intf))
- continue;
-
- _interfaceQueue.addLast(intf);
- _addedInterfaces.add(intf);
- }
- }
-
- public Iterator<Class> iterator()
- {
- return this;
- }
-
- public boolean hasNext()
- {
- return _state != State.DONE;
- }
-
- public Class next()
- {
- switch (_state)
- {
- case CLASS:
-
- Class result = _searchClass;
-
- _searchClass = parentOf(_searchClass);
-
- if (_searchClass == null)
- _state = State.INTERFACE;
- else
- queueInterfaces(_searchClass);
-
- return result;
-
- case INTERFACE:
-
- if (_interfaceQueue.isEmpty())
- {
- _state = State.DONE;
- return Object.class;
- }
-
- Class intf = _interfaceQueue.removeFirst();
-
- queueInterfaces(intf);
-
- return intf;
-
- default:
- throw new IllegalStateException();
- }
-
- }
-
- /**
- * Returns the parent of the given class. Tweaks inheritance for object
arrays. Returns null
- * instead of Object.class.
- */
- private Class parentOf(Class clazz)
- {
- if (clazz.isArray() && clazz != Object[].class)
- {
- Class componentType = clazz.getComponentType();
-
- while (componentType.isArray())
- componentType = componentType.getComponentType();
-
- if (!componentType.isPrimitive())
- return Object[].class;
- }
-
- Class parent = clazz.getSuperclass();
-
- return parent != Object.class ? parent : null;
- }
-
- /**
- * @throws UnsupportedOperationException
- * always
- */
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-
-}
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+
+import org.apache.tapestry.ioc.services.ClassFabUtils;
+
+/**
+ * Used to search from a particular class up the inheritance hierarchy of
extended classes and
+ * implemented interfaces.
+ * <p>
+ * The search starts with the initial class (provided in the constructor). It
progresses up the
+ * inheritance chain, but skips java.lang.Object.
+ * <p>
+ * Once classes are exhausted, the inheritance hiearchy is searched. This is a
breadth-first search,
+ * rooted in the interfaces implemented by the initial class at its super
classes.
+ * <p>
+ * Once all interfaces are exhausted, java.lang.Object is returned (it is
always returned last).
+ * <p>
+ * Two minor tweak to normal inheritance rules:
+ * <ul>
+ * <li> Normally, the parent class of an <em>object</em> array is
java.lang.Object, which is odd
+ * because Foo[] is assignable to Object[]. Thus, we tweak the search so that
the effective super
+ * class of Foo[] is Object[].
+ * <li> The "super class" of a primtive type is its <em>wrapper type</em>,
with the exception of
+ * void, whose "super class" is left at its normal value (Object.class)
+ * </ul>
+ * <p>
+ * This class implements the [EMAIL PROTECTED] Iterable} interface, so it can
be used directly in a for loop:
+ * <code>
+ * for (Class search : new InheritanceSearch(startClass)) {
+ * ...
+ * }
+ * </code>
+ * <p>
+ * This class is not threadsafe.
+ */
+public class InheritanceSearch implements Iterator<Class>, Iterable<Class>
+{
+ private Class _searchClass;
+
+ private final Set<Class> _addedInterfaces = newSet();
+
+ private final LinkedList<Class> _interfaceQueue = newLinkedList();
+
+ private enum State
+ {
+ CLASS, INTERFACE, DONE;
+ }
+
+ private State _state;
+
+ public InheritanceSearch(Class searchClass)
+ {
+ _searchClass = searchClass;
+
+ queueInterfaces(searchClass);
+
+ _state = searchClass == Object.class ? State.INTERFACE : State.CLASS;
+ }
+
+ private void queueInterfaces(Class searchClass)
+ {
+ for (Class intf : searchClass.getInterfaces())
+ {
+ if (_addedInterfaces.contains(intf)) continue;
+
+ _interfaceQueue.addLast(intf);
+ _addedInterfaces.add(intf);
+ }
+ }
+
+ public Iterator<Class> iterator()
+ {
+ return this;
+ }
+
+ public boolean hasNext()
+ {
+ return _state != State.DONE;
+ }
+
+ public Class next()
+ {
+ switch (_state)
+ {
+ case CLASS:
+
+ Class result = _searchClass;
+
+ _searchClass = parentOf(_searchClass);
+
+ if (_searchClass == null)
+ _state = State.INTERFACE;
+ else
+ queueInterfaces(_searchClass);
+
+ return result;
+
+ case INTERFACE:
+
+ if (_interfaceQueue.isEmpty())
+ {
+ _state = State.DONE;
+ return Object.class;
+ }
+
+ Class intf = _interfaceQueue.removeFirst();
+
+ queueInterfaces(intf);
+
+ return intf;
+
+ default:
+ throw new IllegalStateException();
+ }
+
+ }
+
+ /**
+ * Returns the parent of the given class. Tweaks inheritance for object
arrays. Returns null
+ * instead of Object.class.
+ */
+ private Class parentOf(Class clazz)
+ {
+ if (clazz != void.class && clazz.isPrimitive()) return
ClassFabUtils.getWrapperType(clazz);
+
+ if (clazz.isArray() && clazz != Object[].class)
+ {
+ Class componentType = clazz.getComponentType();
+
+ while (componentType.isArray())
+ componentType = componentType.getComponentType();
+
+ if (!componentType.isPrimitive()) return Object[].class;
+ }
+
+ Class parent = clazz.getSuperclass();
+
+ return parent != Object.class ? parent : null;
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
Modified:
tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java?view=diff&rev=499164&r1=499163&r2=499164
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java
(original)
+++
tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/util/InheritanceSearchTest.java
Tue Jan 23 14:32:18 2007
@@ -12,143 +12,162 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.ioc.internal.util;
-
+package org.apache.tapestry.ioc.internal.util;
+
import java.io.Serializable;
import java.util.List;
import org.apache.tapestry.ioc.test.TestBase;
import org.testng.annotations.Test;
-
-/**
- *
- */
-public class InheritanceSearchTest extends TestBase
-{
-
- @Test
- public void remove_always_fails()
- {
- try
- {
- new InheritanceSearch(Object.class).remove();
- unreachable();
- }
- catch (UnsupportedOperationException ex)
- {
-
- }
- }
-
- @Test
- public void next_when_no_more()
- {
- InheritanceSearch s = new InheritanceSearch(Object.class);
-
- assertSame(s.next(), Object.class);
- assertFalse(s.hasNext());
-
- try
- {
- s.next();
- unreachable();
- }
- catch (IllegalStateException ex)
- {
-
- }
- }
-
- @Test
- public void inheritance_of_object()
- {
- check(Object.class, Object.class);
- }
-
- @Test
- public void inheritance_of_string()
- {
- check(
- String.class,
- String.class,
- Serializable.class,
- Comparable.class,
- CharSequence.class,
- Object.class);
- }
-
- @Test
- public void inheritance_of_an_interface()
- {
- check(Comparable.class, Comparable.class, Object.class);
- }
-
- @Test
- public void inheritance_search_order_for_interfaces()
- {
- check(FooBar.class, FooBar.class, Foo.class, Bar.class, Object.class);
- }
-
- @Test
- public void inheritance_search_order_for_classes()
- {
- check(
- FooBarImpl.class,
- FooBarImpl.class,
- FooImpl.class,
- BarImpl.class,
- Bar.class,
- FooBar.class,
- Foo.class,
- Object.class);
-
- }
-
- @Test
- public void inheritance_of_primitive_array()
- {
- check(long[].class, long[].class, Cloneable.class, Serializable.class,
Object.class);
- }
-
- @Test
- public void inheritance_of_a_2d_primitive_array()
- {
- check(int[][].class, int[][].class, Cloneable.class,
Serializable.class, Object.class);
- }
-
- @Test
- public void inheritance_of_an_object_array()
- {
- check(
- String[].class,
- String[].class,
- Object[].class,
- Cloneable.class,
- Serializable.class,
- Object.class);
- }
-
- @Test
- public void inheritance_of_a_2d_object_array()
- {
- check(
- String[][].class,
- String[][].class,
- Object[].class,
- Cloneable.class,
- Serializable.class,
- Object.class);
- }
-
- private void check(Class searchClass, Class... expected)
- {
- List<Class> list = CollectionFactory.newList();
-
- // This for loop is how the class is generally used:
-
- for (Class c : new InheritanceSearch(searchClass))
- list.add(c);
-
- assertEquals(list.toArray(), expected);
- }
-}
+
+/**
+ *
+ */
+public class InheritanceSearchTest extends TestBase
+{
+
+ @Test
+ public void remove_always_fails()
+ {
+ try
+ {
+ new InheritanceSearch(Object.class).remove();
+ unreachable();
+ }
+ catch (UnsupportedOperationException ex)
+ {
+
+ }
+ }
+
+ @Test
+ public void next_when_no_more()
+ {
+ InheritanceSearch s = new InheritanceSearch(Object.class);
+
+ assertSame(s.next(), Object.class);
+ assertFalse(s.hasNext());
+
+ try
+ {
+ s.next();
+ unreachable();
+ }
+ catch (IllegalStateException ex)
+ {
+
+ }
+ }
+
+ @Test
+ public void inheritance_of_object()
+ {
+ check(Object.class, Object.class);
+ }
+
+ @Test
+ public void inheritance_of_string()
+ {
+ check(
+ String.class,
+ String.class,
+ Serializable.class,
+ Comparable.class,
+ CharSequence.class,
+ Object.class);
+ }
+
+ @Test
+ public void inheritance_of_an_interface()
+ {
+ check(Comparable.class, Comparable.class, Object.class);
+ }
+
+ @Test
+ public void inheritance_search_order_for_interfaces()
+ {
+ check(FooBar.class, FooBar.class, Foo.class, Bar.class, Object.class);
+ }
+
+ @Test
+ public void inheritance_search_order_for_classes()
+ {
+ check(
+ FooBarImpl.class,
+ FooBarImpl.class,
+ FooImpl.class,
+ BarImpl.class,
+ Bar.class,
+ FooBar.class,
+ Foo.class,
+ Object.class);
+
+ }
+
+ @Test
+ public void inheritance_of_primitive()
+ {
+ check(
+ long.class,
+ long.class,
+ Long.class,
+ Number.class,
+ Comparable.class,
+ Serializable.class,
+ Object.class);
+ }
+
+ @Test
+ public void inheritance_of_void()
+ {
+ check(void.class, void.class, Object.class);
+ }
+
+ @Test
+ public void inheritance_of_primitive_array()
+ {
+ check(long[].class, long[].class, Cloneable.class, Serializable.class,
Object.class);
+ }
+
+ @Test
+ public void inheritance_of_a_2d_primitive_array()
+ {
+ check(int[][].class, int[][].class, Cloneable.class,
Serializable.class, Object.class);
+ }
+
+ @Test
+ public void inheritance_of_an_object_array()
+ {
+ check(
+ String[].class,
+ String[].class,
+ Object[].class,
+ Cloneable.class,
+ Serializable.class,
+ Object.class);
+ }
+
+ @Test
+ public void inheritance_of_a_2d_object_array()
+ {
+ check(
+ String[][].class,
+ String[][].class,
+ Object[].class,
+ Cloneable.class,
+ Serializable.class,
+ Object.class);
+ }
+
+ private void check(Class searchClass, Class... expected)
+ {
+ List<Class> list = CollectionFactory.newList();
+
+ // This for loop is how the class is generally used:
+
+ for (Class c : new InheritanceSearch(searchClass))
+ list.add(c);
+
+ assertEquals(list.toArray(), expected);
+ }
+}