org.apache.cxf.aegis.type.collection.CollectionType createCollection method 
returns ArrayList object for typeClass java.util.SortedSet
--------------------------------------------------------------------------------------------------------------------------------------

                 Key: CXF-1770
                 URL: https://issues.apache.org/jira/browse/CXF-1770
             Project: CXF
          Issue Type: Bug
          Components: Aegis Databinding
    Affects Versions: 2.1.2
         Environment: Microsoft Windows XP, Java 1.5.0.14, Tomcat 5.5
            Reporter: Sarah Haskins
            Priority: Minor


In attempting to populate a POJO with the response from a WSDL using Aegis 
databinding, I am getting the exception...

Caused by: org.apache.cxf.aegis.DatabindingException: No write method for 
property {http://domain.webmap.gis.doitt.nyc.gov}fields in class 
gov.nyc.doitt.gis.webmap.domain.DataStoreRenderer
        at 
org.apache.cxf.aegis.type.basic.BeanType.writeProperty(BeanType.java:243)
        at 
org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:147)
        at 
org.apache.cxf.aegis.type.basic.ArrayType.readCollection(ArrayType.java:89)
        at 
org.apache.cxf.aegis.type.collection.CollectionType.readObject(CollectionType.java:48)
        at 
org.apache.cxf.aegis.type.basic.BeanType.readObject(BeanType.java:145)
        at 
org.apache.cxf.aegis.AegisXMLStreamDataReader.read(AegisXMLStreamDataReader.java:82)
        at 
org.apache.cxf.aegis.databinding.XMLStreamDataReader.read(XMLStreamDataReader.java:47)

My POJOs looks like:

public class DataStoreRenderer extends Persistent {
        private SortedSet<DataStoreRendererField> fields = new 
TreeSet<DataStoreRendererField>();
        ...

        public SortedSet<DataStoreRendererField> getFields() {
                return fields;
        }
        
        public void setFields(SortedSet<DataStoreRendererField> fields) {
                this.fields = fields;
        }
        ...
}

public class DataStoreRendererField implements 
Comparable<DataStoreRendererField> {
        ...
        public int compareTo(DataStoreRendererField o) {
                ...
        }
}

A simplied version of the response being bound looks like this...

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";>
    <soap:Body>
        <ns1:getApplicationResponse 
xmlns:ns1="http://service.webmap.gis.doitt.nyc.gov/";>
            <application>
                <ns2:dataStoreRenderers 
xmlns:ns2="http://domain.webmap.gis.doitt.nyc.gov";>
                    <ns2:DataStoreRenderer>
                    <ns2:fields>
                        <ns2:DataStoreRendererField>
                            <ns2:id>1</ns2:id>
                        </ns2:DataStoreRendererField>
                        <ns2:DataStoreRendererField>
                            <ns2:id>2</ns2:id>
                        </ns2:DataStoreRendererField>
                        <ns2:DataStoreRendererField>
                            <ns2:id>3</ns2:id>
                        </ns2:DataStoreRendererField>
                        <ns2:DataStoreRendererField>
                            <ns2:id>4</ns2:id>
                        </ns2:DataStoreRendererField>
                    </ns2:fields>
                    </ns2:DataStoreRenderer>
                </ns2:dataStoreRenderers>
            </application>
        </ns1:getApplicationResponse>
    </soap:Body>
</soap:Envelope>

After debugging through the code I found that the exception is thrown because 
there xml is converted into an ArrayList and then when an appropriate setter is 
looked for we cannot find any that take ArrayList.  Once I found that out I 
debugged some more and found that the 
org.apache.cxf.aegis.type.collection.CollectionType.createCollection() method 
was the one creating the ArrayList.  The solution I had in mind was simply to 
add another else if statement (between List and Set) inside this 
createCollection method that would do the following...

protected Collection<Object> createCollection() {
        Collection values = null;

        if (getTypeClass().isAssignableFrom(List.class)) {
            values = new ArrayList();
        } else if (getTypeClass().isAssignableFrom(SortedSet.class)) {
            values = new TreeSet();
        } else if (getTypeClass().isAssignableFrom(Set.class)) {
            values = new HashSet();
        } else if (getTypeClass().isAssignableFrom(Vector.class)) {
            values = new Vector();
        } else if (getTypeClass().isInterface()) {
            values = new ArrayList();
        } else {
            try {
                values = (Collection<Object>)getTypeClass().newInstance();
            } catch (Exception e) {
                throw new DatabindingException("Could not create map 
implementation: "
                                               + getTypeClass().getName(), e);
            }
        }

        return values;
    }

Although it is possible that not everyone has implemented Comparable on the 
object contained in a SortedSet, wouldn't it be better to at least create a 
TreeSet as the default, rather than an ArrayList?  That way no exception will 
be thrown and the code won't fail to complete?

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to