Hello Folks,

Recently I came across a small shortcoming (IMHO) in the way Wicket's
default IConverterLocator implementation handles inheritance. It seems
that the ConverterLocator only returns an IConverter, if one is
registered for the exact given Class. If such an IConverter is not
present, it returns null. 

However, any IConverter that is capable of converting a superclass of
the given Class, might also be suitable. For instance, if an IConverter
for Class ArrayList is requested, a more generic IConverter for Class
List might work as well.

It might be handy to register a generic IConverter for a supertype of
the class hierarchy and let it handle conversion for all subclasses.
This would also allow to register IConverters for abstract classes and
interfaces. And it might solve certain problems people have reported
about converting CGLib-enhanced proxy objects, like the ones often
returned by Hibernate.


In my Wicket app, I use a custom HierarchicConverterLocator, that
searches for IConverters using the superclass hierarchy. It is a
quick-and-dirty implementation, without any performance optimizations.
But it works very well for me!

If anyone thinks this might be useful, I can do a little more effort and
maybe contribute it. You can find (most of) the code below...


Regards,
Michael Riedel



/**
 *
 */
public class HierarchicConverterLocator implements IConverterLocator
{       
        /** */
        private ConverterLocator converterLocator = 
                        new ConverterLocator();

        /**
         * 
         */
        @Override
        public IConverter getConverter( Class<?> type )
        {
                final IConverter converter = getConverterOrNull( type );
                if( converter == null )
                {
                        return converterLocator.getConverter( type );
                }
                return converter;
        }
        
        /**
         * 
         */
        private IConverter getConverterOrNull( Class<?> type )
        {
                if( type == null )
                {
                        return null;
                }
                
                final IConverter converter = get( type );
                if( converter == null )
                {
                        final List<Class<?>> superTypes = 
                                new LinkedList<Class<?>>();
                        superTypes.add( type.getSuperclass() );
                        superTypes.addAll( 
                                Arrays.asList( type.getInterfaces() ) 
                                );
                        
                        for( Class<?> superType : superTypes )
                        {
                                final IConverter superTypeConverter = 
                                        getConverterOrNull( superType );
                                if ( superTypeConverter != null )
                                {
                                        return superTypeConverter;
                                }
                        }
                }
                return converter;
        }

        /**
         * 
         */
        public IConverter get( final Class<?> type )
        {
                return converterLocator.get( type );
        }

        /**
         * 
         */
        public IConverter set( final Class<?> c, 
                        final IConverter converter )
        {
                return converterLocator.set( c, converter );
        }
        
        /**
         * 
         */
        public IConverter remove(Class<?> c)
        {
                return converterLocator.remove( c );
        }
}


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to