org.apache.wicket.util.lang.PropertyResolverConverter Type Erasure leads to 
Sloppy Typing
-----------------------------------------------------------------------------------------

                 Key: WICKET-3441
                 URL: https://issues.apache.org/jira/browse/WICKET-3441
             Project: Wicket
          Issue Type: Bug
          Components: wicket
    Affects Versions: 1.5-RC1
         Environment: all
            Reporter: Richard Emberson
            Priority: Minor


There seems to be some problems with the
org.apache.wicket.util.lang.PropertyResolverConverter convert method
that the Java compiler lets slip because of type erasure.
To show this, lets let the convert method had type parameterized arguments:

public <OT, CT> Object convert(OT object, Class<CT> clz)

and the converter is then typed:

  IConverter<CT> converter = converterSupplier.getConverter(clz);

then the block of code:

  else if (clz == String.class) {
    return converter.convertToString(object, locale);
  }

has an issue because the convertToString expects object to have
type CT. Because of type erasure, the Java compiler lets this
slip by. In addition, since the class type is String, the
converter used is just the ConverterLocator,DefaultConverter
whose convertToString method ends up calling

    return (String)Objects.convertValue(value, String.class);

which, when nothing can be found to convert to a "known" value
simply returns the value parameter. Again, all this is allowed
because the Java compiler gets sloppy due to type erasure.
But calling Objects.convertValue is just what the block of code
following the above convert method code does:

  else {
    try {
     return Objects.convertValue(object, clz);
    } catch (RuntimeException ex) {
     // ignore that try it the other way
    }
    // go through string to convert to the right object.
    String tmp = converter.convertToString(object, locale);
    return converter.convertToObject(tmp, locale);
  }

So, the previous block of code:

  else if (clz == String.class) {
    return converter.convertToString(object, locale);
  }

can be removed 1) allowing for correct typing and 2) with the
same results.

Also, if one examines the code:

    // go through string to convert to the right object.
    String tmp = converter.convertToString(object, locale);
    return converter.convertToObject(tmp, locale);

one sees that this has the same sloppy typing as the code block
just remove, that is:

    return converter.convertToString(object, locale);

Again, object is of type OT while the convertToString method
of the IConverter is expecting a type of CT.
The fix is to use an IConverter of the type of OT to convert to
String and then the IConverter of type CT to convert to the
return object:

    // go through string to convert to the right object.
    IConverter<OT> converterForObj =
        converterSupplier.getConverter(object.getClass());
    String tmp = converterForObj.convertToString(object, locale);
    return converter.convertToObject(tmp, locale);

This is now correctly typed.

I noticed this because there is rather more theory behind Scala's
type system than Java's so that the Scala compiler complained about
the attempt to sneak around the type erasure.


-- 
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to