Hi Dmitry,

depst...@alliedtesting.com wrote:

> OK, I just realized that I misdiagnozed the problem. What actually happens
> is that CollectionConverter is initialized with the List type, because
> that is the declared type of the field. The actual type of the field
> (ArrayList) differs from the type with which the converter was
> initialized, which is why it won't work. Here is the canConvert method in
> CollectionConverter:
> 
>     public boolean canConvert(Class type) {
>         if (this.type != null) {
>             return type.equals(this.type);
>         }
>         return type.equals(ArrayList.class)
>             || type.equals(HashSet.class)
>             || type.equals(LinkedList.class)
>             || type.equals(Vector.class)
>             || (JVM.is14() &&
>             || type.getName().equals("java.util.LinkedHashSet"));
>     }
> 
> this.type is List, and type is ArrayList. Perhaps this would be better?
> 
>             return type.isAssignableFrom(this.type);

Definitely not, because XStream cannot know what else a different Collection 
implementation keeps internally. E.g. it would forget about a TreeSet's 
comparator or an unmodifiable list would no longer be unmodifiable.

> Here is a complete example:
> 
> import java.io.File;
> import java.io.FileNotFoundException;
> import java.io.PrintWriter;
> import java.util.ArrayList;
> import java.util.List;
> 
> import com.thoughtworks.xstream.XStream;
> import com.thoughtworks.xstream.annotations.XStreamConverter;
> import
> com.thoughtworks.xstream.converters.collections.CollectionConverter;
> import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import
> com.thoughtworks.xstream.io.xml.StaxDriver;
> 
> public class ItemList {
> 
> @XStreamConverter(CollectionConverter.class)
> public List<String> items = new ArrayList<String>();

[snip]

Look at the Javadoc for the XStreamConverter annotation. XStream performs a 
poor man's constructor dependency injection. The constructor with the most 
arguments is considered first, possible parameters are the current type (in 
your case List.class), some standard XStream objects and anything you 
provide as static parameter for the annotation.

The declaration to initialize a CollectionConverter is a bit tricky though, 
because you do *not* want to consider the current type:

@XStreamConverter(value=CollectionConverter.class, types={ArrayList.class}, 
useImplicitType = false)

Have a look at 
com.thoughtworks.acceptance.annotations.ParametrizedConverterTest for more 
examples.

[snip]

> I get an exception with XStream 1.4.6.1:

?!? What is XStream 1.4.6.1? We release 1.4.6 and 1.4.7, but nothing 
inbetween.

[snip]

Hope this helps,
Jörg



---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to