> The way I did this was:
> 
> TypedStructure interface. AbstractTypedStructure class.
> IllegalTypeException exception.
> 
> Then TypedSet/List/Map implement Set/List/Map and extend
> AbstractTypedStructure.

Hehehehe...we *could* use dynamic proxy classes to provide 
one factory method that would work for all collections and
maps...

This isn't a serious suggestion, just proof that I have way
too much time on my hands...

-Paul


package org.apache.commons.collections;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;


public class PredicateCollectionFactory
{

        static class PredicateInvocationHandler implements InvocationHandler
        {
                private Predicate predicate;
                private Object target;


                public PredicateInvocationHandler(Object target, Predicate
predicate)
                {
                        this.target = target;
                        this.predicate = predicate;
                }


                public Object invoke(Object proxy, Method method, Object[]
parameters) throws Throwable
                {
                        if (method.getName().equals("equals"))
                        {
                                return defaultInvoke(target, method,
parameters);
                        }
                        Class[] types = method.getParameterTypes();
                        for (int i = 0; i < types.length; i++)
                        {
                                if ((types[i] == Object.class) &&
!predicate.evaluate(parameters[i]))
                                {
                                        throw new
IllegalArgumentException();
                                }
                        }
                        return defaultInvoke(target, method, parameters);
                }


                static Object defaultInvoke(Object target, Method method,
Object[] parameters) throws Throwable
                {
                        try
                        {
                                return method.invoke(target, parameters);
                        }
                        catch (InvocationTargetException e)
                        {
                                throw e.getTargetException();
                        }
                }
        }


        private static Class[] getAllInterfaces(Object object)
        {
                HashSet set = new HashSet();
                for (Class c = object.getClass(); c != null; c =
c.getSuperclass())
                {
                        set.addAll(Arrays.asList(c.getInterfaces()));
                }
                return (Class[])set.toArray(new Class[set.size()]);
        }


        public static Object create(Object collection, Predicate predicate)
        {
                InvocationHandler handler = new
PredicateInvocationHandler(collection, predicate);
                Class[] interfaces = getAllInterfaces(collection);
                ClassLoader loader =
PredicateCollectionFactory.class.getClassLoader();
                return Proxy.newProxyInstance(loader, interfaces, handler);
        }


        // Example usage...
        public static void main(String args[])
        {
                java.util.List list = new java.util.ArrayList();
                Predicate predicate = new Predicate() {
                        public boolean evaluate(Object object)
                        {
                                return (object instanceof String);
                        }
                };
                list = (java.util.List)create(list, predicate);
                list.add("Hello, nurse!");  // works fine
                list.add(new Integer(4)); // will raise
IllegalArgumentException
        }

}


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to