You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-dev@ws.apache.org by "Vinh Nguyen (JIRA)" <ji...@apache.org> on 2007/07/13 11:45:04 UTC

[jira] Created: (MUSE-249) ReflectionProxyHandler.fromXML() improperly handles complex response type containing multiple child elements

ReflectionProxyHandler.fromXML() improperly handles complex response type containing multiple child elements
------------------------------------------------------------------------------------------------------------

                 Key: MUSE-249
                 URL: https://issues.apache.org/jira/browse/MUSE-249
             Project: Muse
          Issue Type: Bug
            Reporter: Vinh Nguyen
            Assignee: Dan Jemiolo


This is somewhat related to MUSE-248 but is a separate problem on its own.

My server capability returns the following response:

    <xs:element name="EnumerateResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Expires" type="tns:ExpirationType" minOccurs="0"/>
                <xs:element name="EnumerationContext" type="tns:EnumerationContextType"/>
                <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:anyAttribute namespace="##other" processContents="lax"/>
        </xs:complexType>
    </xs:element>

But, when my EnumerateResponseSerializer.fromXML() is called, it receives only the first child element of the response (i.e. the "Expires" element).

The problem is in ReflectionProxyHandler.fromXML() in this code chunk:

        //
        // if the value is a simple type, use the root of the 
        // response body
        //
        Element child = XmlUtils.getFirstElement(xml);
        Class returnType = getReturnType();
        
        if (child == null || returnType.isArray())
            child = xml;
        //
        // now we can deserialize the contents
        //
        return deserialize(child, returnType);

If the response is a complex type, Muse only takes the first child element and sends it to the serializer.  But my serializer is expecting the entire EnumerateResponse because my client code needs all the child elements.

The easiest fix is to update to the following:

        Element child = null;
        Element[] all = XmlUtils.getAllElements(xml);
        if (all.length == 0 || all.length > 1 || returnType.isArray())
            child = xml;
        else
            child = all[0];

Basically, it just adds one additional logic: if there are multiple children, deserialize the entire original Element.  So only deserialize and return the first child if that's the only child.  I think we can safely assume that if an operation returns a response containing multiple child elements, a client will be expecting the deserialized response as one object.  In this case, my client can safely expect one EnumerateResponse object.

Just returning the children in an Object[] is useless unless the client knows the exact types and how many children to expect beforehand.  Also, a serializer can only take in one object at at time, not an array of child objects.

Overall, I think the real problem is this:
A wsdl allows an operation response to contain multiple children.  This is like a method returning multiple non-homogenous objects not in a collection.  This is not possible in Java because a method can only return one object, or an Object[], but not multiple objects that are not in a single collection.  So for web services, we have to assume that if a client receives a response that is not a homogenous array of objects, the client can only work with the data if it directly accessed the response wrapper object itself so that specific child objects can be extracted as needed.


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


---------------------------------------------------------------------
To unsubscribe, e-mail: muse-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-dev-help@ws.apache.org


[jira] Updated: (MUSE-249) ReflectionProxyHandler.fromXML() improperly handles complex response type containing multiple child elements

Posted by "Dan Jemiolo (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/MUSE-249?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dan Jemiolo updated MUSE-249:
-----------------------------

          Component/s: Core Engine - Routing and Serialization
        Fix Version/s: 2.3.0
    Affects Version/s: 2.2.0

> ReflectionProxyHandler.fromXML() improperly handles complex response type containing multiple child elements
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MUSE-249
>                 URL: https://issues.apache.org/jira/browse/MUSE-249
>             Project: Muse
>          Issue Type: Bug
>          Components: Core Engine - Routing and Serialization
>    Affects Versions: 2.2.0
>            Reporter: Vinh Nguyen
>            Assignee: Dan Jemiolo
>             Fix For: 2.3.0
>
>
> This is somewhat related to MUSE-248 but is a separate problem on its own.
> My server capability returns the following response:
>     <xs:element name="EnumerateResponse">
>         <xs:complexType>
>             <xs:sequence>
>                 <xs:element name="Expires" type="tns:ExpirationType" minOccurs="0"/>
>                 <xs:element name="EnumerationContext" type="tns:EnumerationContextType"/>
>                 <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
>             </xs:sequence>
>             <xs:anyAttribute namespace="##other" processContents="lax"/>
>         </xs:complexType>
>     </xs:element>
> But, when my EnumerateResponseSerializer.fromXML() is called, it receives only the first child element of the response (i.e. the "Expires" element).
> The problem is in ReflectionProxyHandler.fromXML() in this code chunk:
>         //
>         // if the value is a simple type, use the root of the 
>         // response body
>         //
>         Element child = XmlUtils.getFirstElement(xml);
>         Class returnType = getReturnType();
>         
>         if (child == null || returnType.isArray())
>             child = xml;
>         //
>         // now we can deserialize the contents
>         //
>         return deserialize(child, returnType);
> If the response is a complex type, Muse only takes the first child element and sends it to the serializer.  But my serializer is expecting the entire EnumerateResponse because my client code needs all the child elements.
> The easiest fix is to update to the following:
>         Element child = null;
>         Element[] all = XmlUtils.getAllElements(xml);
>         if (all.length == 0 || all.length > 1 || returnType.isArray())
>             child = xml;
>         else
>             child = all[0];
> Basically, it just adds one additional logic: if there are multiple children, deserialize the entire original Element.  So only deserialize and return the first child if that's the only child.  I think we can safely assume that if an operation returns a response containing multiple child elements, a client will be expecting the deserialized response as one object.  In this case, my client can safely expect one EnumerateResponse object.
> Just returning the children in an Object[] is useless unless the client knows the exact types and how many children to expect beforehand.  Also, a serializer can only take in one object at at time, not an array of child objects.
> Overall, I think the real problem is this:
> A wsdl allows an operation response to contain multiple children.  This is like a method returning multiple non-homogenous objects not in a collection.  This is not possible in Java because a method can only return one object, or an Object[], but not multiple objects that are not in a single collection.  So for web services, we have to assume that if a client receives a response that is not a homogenous array of objects, the client can only work with the data if it directly accessed the response wrapper object itself so that specific child objects can be extracted as needed.

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


---------------------------------------------------------------------
To unsubscribe, e-mail: muse-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-dev-help@ws.apache.org


[jira] Closed: (MUSE-249) ReflectionProxyHandler.fromXML() improperly handles complex response type containing multiple child elements

Posted by "Dan Jemiolo (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/MUSE-249?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Dan Jemiolo closed MUSE-249.
----------------------------

    Resolution: Fixed

Applied the suggested fix

> ReflectionProxyHandler.fromXML() improperly handles complex response type containing multiple child elements
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MUSE-249
>                 URL: https://issues.apache.org/jira/browse/MUSE-249
>             Project: Muse
>          Issue Type: Bug
>          Components: Core Engine - Routing and Serialization
>    Affects Versions: 2.2.0
>            Reporter: Vinh Nguyen
>            Assignee: Dan Jemiolo
>             Fix For: 2.3.0
>
>
> This is somewhat related to MUSE-248 but is a separate problem on its own.
> My server capability returns the following response:
>     <xs:element name="EnumerateResponse">
>         <xs:complexType>
>             <xs:sequence>
>                 <xs:element name="Expires" type="tns:ExpirationType" minOccurs="0"/>
>                 <xs:element name="EnumerationContext" type="tns:EnumerationContextType"/>
>                 <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
>             </xs:sequence>
>             <xs:anyAttribute namespace="##other" processContents="lax"/>
>         </xs:complexType>
>     </xs:element>
> But, when my EnumerateResponseSerializer.fromXML() is called, it receives only the first child element of the response (i.e. the "Expires" element).
> The problem is in ReflectionProxyHandler.fromXML() in this code chunk:
>         //
>         // if the value is a simple type, use the root of the 
>         // response body
>         //
>         Element child = XmlUtils.getFirstElement(xml);
>         Class returnType = getReturnType();
>         
>         if (child == null || returnType.isArray())
>             child = xml;
>         //
>         // now we can deserialize the contents
>         //
>         return deserialize(child, returnType);
> If the response is a complex type, Muse only takes the first child element and sends it to the serializer.  But my serializer is expecting the entire EnumerateResponse because my client code needs all the child elements.
> The easiest fix is to update to the following:
>         Element child = null;
>         Element[] all = XmlUtils.getAllElements(xml);
>         if (all.length == 0 || all.length > 1 || returnType.isArray())
>             child = xml;
>         else
>             child = all[0];
> Basically, it just adds one additional logic: if there are multiple children, deserialize the entire original Element.  So only deserialize and return the first child if that's the only child.  I think we can safely assume that if an operation returns a response containing multiple child elements, a client will be expecting the deserialized response as one object.  In this case, my client can safely expect one EnumerateResponse object.
> Just returning the children in an Object[] is useless unless the client knows the exact types and how many children to expect beforehand.  Also, a serializer can only take in one object at at time, not an array of child objects.
> Overall, I think the real problem is this:
> A wsdl allows an operation response to contain multiple children.  This is like a method returning multiple non-homogenous objects not in a collection.  This is not possible in Java because a method can only return one object, or an Object[], but not multiple objects that are not in a single collection.  So for web services, we have to assume that if a client receives a response that is not a homogenous array of objects, the client can only work with the data if it directly accessed the response wrapper object itself so that specific child objects can be extracted as needed.

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


---------------------------------------------------------------------
To unsubscribe, e-mail: muse-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-dev-help@ws.apache.org