You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2006/12/29 23:41:13 UTC

svn commit: r491124 - in /tapestry/tapestry5/tapestry-ioc/trunk/src: main/java/org/apache/tapestry/ioc/internal/services/ test/java/org/apache/tapestry/ioc/ test/java/org/apache/tapestry/ioc/internal/services/

Author: hlship
Date: Fri Dec 29 14:41:12 2006
New Revision: 491124

URL: http://svn.apache.org/viewvc?view=rev&rev=491124
Log:
Change PropertyAccessor to show properties inherited from extended interfaces, when the class being introspected is an interface (java.beans.Introspector does not do this automatically)

Added:
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java
Modified:
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderOverrideTest.java
    tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java?view=diff&rev=491124&r1=491123&r2=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/ClassPropertyAdapterImpl.java Fri Dec 29 14:41:12 2006
@@ -12,75 +12,72 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.ioc.internal.services;
-
+package org.apache.tapestry.ioc.internal.services;
+
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
-
-import java.beans.PropertyDescriptor;
-import java.util.List;
-import java.util.Map;
-
+
+import java.beans.PropertyDescriptor;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
-import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
-import org.apache.tapestry.ioc.services.PropertyAdapter;
-
-/**
- * 
- */
-public class ClassPropertyAdapterImpl implements ClassPropertyAdapter
-{
-    private final Map<String, PropertyAdapter> _adapters = newMap();
-
-    private final Class _targetClass;
-
-    public ClassPropertyAdapterImpl(Class targetClass, PropertyDescriptor[] descriptors)
-    {
-        _targetClass = targetClass;
-
-        for (PropertyDescriptor pd : descriptors)
-        {
-            PropertyAdapter pa = new PropertyAdapterImpl(pd);
-
-            _adapters.put(pa.getName(), pa);
-        }
-    }
-
-    @Override
-    public String toString()
-    {
-        String names = InternalUtils.joinSorted(_adapters.keySet());
-
-        return String.format("<ClassPropertyAdaptor %s : %s>", _targetClass.getName(), names);
-    }
-
-    public List<String> getPropertyNames()
-    {
-        return InternalUtils.sortedKeys(_adapters);
-    }
-
-    public PropertyAdapter getPropertyAdapter(String name)
-    {
-        return _adapters.get(name);
-    }
-
-    public Object get(Object instance, String propertyName)
-    {
-        return adaptorFor(propertyName).get(instance);
-    }
-
-    public void set(Object instance, String propertyName, Object value)
-    {
-        adaptorFor(propertyName).set(instance, value);
-    }
-
-    private PropertyAdapter adaptorFor(String name)
-    {
-        PropertyAdapter pa = _adapters.get(name);
-
-        if (pa == null)
-            throw new IllegalArgumentException(ServiceMessages.noSuchProperty(_targetClass, name));
-
-        return pa;
-    }
-
-}
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
+
+public class ClassPropertyAdapterImpl implements ClassPropertyAdapter
+{
+    private final Map<String, PropertyAdapter> _adapters = newMap();
+
+    private final Class _targetClass;
+
+    public ClassPropertyAdapterImpl(Class targetClass, List<PropertyDescriptor> descriptors)
+    {
+        _targetClass = targetClass;
+
+        for (PropertyDescriptor pd : descriptors)
+        {
+            PropertyAdapter pa = new PropertyAdapterImpl(pd);
+
+            _adapters.put(pa.getName(), pa);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        String names = InternalUtils.joinSorted(_adapters.keySet());
+
+        return String.format("<ClassPropertyAdaptor %s : %s>", _targetClass.getName(), names);
+    }
+
+    public List<String> getPropertyNames()
+    {
+        return InternalUtils.sortedKeys(_adapters);
+    }
+
+    public PropertyAdapter getPropertyAdapter(String name)
+    {
+        return _adapters.get(name);
+    }
+
+    public Object get(Object instance, String propertyName)
+    {
+        return adaptorFor(propertyName).get(instance);
+    }
+
+    public void set(Object instance, String propertyName, Object value)
+    {
+        adaptorFor(propertyName).set(instance, value);
+    }
+
+    private PropertyAdapter adaptorFor(String name)
+    {
+        PropertyAdapter pa = _adapters.get(name);
+
+        if (pa == null)
+            throw new IllegalArgumentException(ServiceMessages.noSuchProperty(_targetClass, name));
+
+        return pa;
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java?view=diff&rev=491124&r1=491123&r2=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/main/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImpl.java Fri Dec 29 14:41:12 2006
@@ -12,76 +12,115 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.ioc.internal.services;
-
+package org.apache.tapestry.ioc.internal.services;
+
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newLinkedList;
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newThreadSafeMap;
-
-import java.beans.BeanInfo;
-import java.beans.Introspector;
-import java.util.Map;
-
-import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
-import org.apache.tapestry.ioc.services.PropertyAccess;
-
-public class PropertyAccessImpl implements PropertyAccess
-{
-    private final Map<Class, ClassPropertyAdapter> _adapters = newThreadSafeMap();
-
-    public Object get(Object instance, String propertyName)
-    {
-        return getAdapter(instance).get(instance, propertyName);
-    }
-
-    public void set(Object instance, String propertyName, Object value)
-    {
-        getAdapter(instance).set(instance, propertyName, value);
-    }
-
-    /** Clears the cache of adapters and asks the Introspector to clear its cache. */
-    public synchronized void clearCache()
-    {
-        _adapters.clear();
-
-        Introspector.flushCaches();
-    }
-
-    public ClassPropertyAdapter getAdapter(Object instance)
-    {
-        return getAdapter(instance.getClass());
-    }
-
-    public ClassPropertyAdapter getAdapter(Class forClass)
-    {
-        ClassPropertyAdapter result = _adapters.get(forClass);
-
-        if (result == null)
-        {
-            result = buildAdapter(forClass);
-            _adapters.put(forClass, result);
-        }
-
-        return result;
-    }
-
-    /**
-     * Builds a new adapter and updates the _adapters cache. This not only guards access to the
-     * adapter cache, but also serializes access to the Java Beans Introspector, which is not thread
-     * safe.
-     */
-    private synchronized ClassPropertyAdapter buildAdapter(Class forClass)
-    {
-        // In some race conditions, we may hit this method for the same class multiple times.
-        // We just let it happen, replacing the old ClassPropertyAdapter with a new one.
-
-        try
-        {
-            BeanInfo info = Introspector.getBeanInfo(forClass);
-
-            return new ClassPropertyAdapterImpl(forClass, info.getPropertyDescriptors());
-        }
-        catch (Throwable ex)
-        {
-            throw new RuntimeException(ex);
-        }
-    }
-}
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tapestry.ioc.services.ClassPropertyAdapter;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+
+public class PropertyAccessImpl implements PropertyAccess
+{
+    private final Map<Class, ClassPropertyAdapter> _adapters = newThreadSafeMap();
+
+    public Object get(Object instance, String propertyName)
+    {
+        return getAdapter(instance).get(instance, propertyName);
+    }
+
+    public void set(Object instance, String propertyName, Object value)
+    {
+        getAdapter(instance).set(instance, propertyName, value);
+    }
+
+    /** Clears the cache of adapters and asks the Introspector to clear its cache. */
+    public synchronized void clearCache()
+    {
+        _adapters.clear();
+
+        Introspector.flushCaches();
+    }
+
+    public ClassPropertyAdapter getAdapter(Object instance)
+    {
+        return getAdapter(instance.getClass());
+    }
+
+    public ClassPropertyAdapter getAdapter(Class forClass)
+    {
+        ClassPropertyAdapter result = _adapters.get(forClass);
+
+        if (result == null)
+        {
+            result = buildAdapter(forClass);
+            _adapters.put(forClass, result);
+        }
+
+        return result;
+    }
+
+    /**
+     * Builds a new adapter and updates the _adapters cache. This not only guards access to the
+     * adapter cache, but also serializes access to the Java Beans Introspector, which is not thread
+     * safe. In addition, handles the case where the class in question is an interface, accumulating
+     * properties inherited from super-classes.
+     */
+    private synchronized ClassPropertyAdapter buildAdapter(Class forClass)
+    {
+        // In some race conditions, we may hit this method for the same class multiple times.
+        // We just let it happen, replacing the old ClassPropertyAdapter with a new one.
+
+        try
+        {
+            BeanInfo info = Introspector.getBeanInfo(forClass);
+
+            List<PropertyDescriptor> descriptors = newList();
+
+            addAll(descriptors, info.getPropertyDescriptors());
+
+            if (forClass.isInterface()) addPropertiesFromExtendedInterfaces(forClass, descriptors);
+
+            return new ClassPropertyAdapterImpl(forClass, descriptors);
+        }
+        catch (Throwable ex)
+        {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private <T> void addAll(List<T> list, T[] array)
+    {
+        for (T i : array)
+            list.add(i);
+    }
+
+    private void addPropertiesFromExtendedInterfaces(Class forClass,
+            List<PropertyDescriptor> descriptors) throws IntrospectionException
+    {
+        LinkedList<Class> queue = newLinkedList();
+
+        // Seed the queue
+        addAll(queue, forClass.getInterfaces());
+
+        while (!queue.isEmpty())
+        {
+            Class c = queue.removeFirst();
+
+            BeanInfo info = Introspector.getBeanInfo(c);
+
+            addAll(descriptors, info.getPropertyDescriptors());
+            addAll(queue, c.getInterfaces());
+        }
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderOverrideTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderOverrideTest.java?view=diff&rev=491124&r1=491123&r2=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderOverrideTest.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/RegistryBuilderOverrideTest.java Fri Dec 29 14:41:12 2006
@@ -1,17 +1,17 @@
-// Copyright 2006 The Apache Software Foundation
-//
-// 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.
-
+// Copyright 2006 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.ioc;
 
 import org.apache.tapestry.ioc.annotations.Id;

Added: tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java?view=auto&rev=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java (added)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/GrandparentInterface.java Fri Dec 29 14:41:12 2006
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.ioc.internal.services;
+
+public interface GrandparentInterface
+{
+    String getGrandParentProperty();
+}

Added: tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java?view=auto&rev=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java (added)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/ParentInterface.java Fri Dec 29 14:41:12 2006
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.ioc.internal.services;
+
+public interface ParentInterface extends GrandparentInterface
+{
+    String getParentProperty();
+}

Modified: tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java?view=diff&rev=491124&r1=491123&r2=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java (original)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java Fri Dec 29 14:41:12 2006
@@ -379,4 +379,14 @@
         assertEquals(b.getValue(), value);
     }
 
+    @Test
+    public void super_interface_methods_inherited_by_sub_interface()
+    {
+        ClassPropertyAdapter cpa = _access.getAdapter(SubInterface.class);
+
+        assertEquals(cpa.getPropertyNames(), Arrays.asList(
+                "grandParentProperty",
+                "parentProperty",
+                "subProperty"));
+    }
 }

Added: tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java?view=auto&rev=491124
==============================================================================
--- tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java (added)
+++ tapestry/tapestry5/tapestry-ioc/trunk/src/test/java/org/apache/tapestry/ioc/internal/services/SubInterface.java Fri Dec 29 14:41:12 2006
@@ -0,0 +1,20 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// 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 org.apache.tapestry.ioc.internal.services;
+
+public interface SubInterface extends ParentInterface
+{
+    String getSubProperty();
+}