You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Craig Muchinsky (JIRA)" <ji...@apache.org> on 2009/04/03 19:24:13 UTC

[jira] Created: (CXF-2153) Support nested parameter injection into beans

Support nested parameter injection into beans
---------------------------------------------

                 Key: CXF-2153
                 URL: https://issues.apache.org/jira/browse/CXF-2153
             Project: CXF
          Issue Type: Improvement
          Components: REST
    Affects Versions: 2.2.1
            Reporter: Craig Muchinsky
             Fix For: 2.2.1


The current CXF extension for handling parameter injection into beans does not handle the case where you want to set values on beans that are within other beans. Take the following simple example:

class Name 
{ 
    String first; 
    String last; 
} 

class Address 
{ 
    String city; 
    String state; 
} 

class Person 
{ 
    Name legalName; 
    Address homeAddr; 
    String race; 
    String sex; 
    Date birthDate; 
} 

class MyService 
{ 
    @GET 
    @Path("/getPerson") 
    Person getPerson(@QueryParam("") Person person); 
} 

I would like to be able to pass something like: 

/getPerson?sex=M&legalName.first=John&legalName.last=Doe&homeAddr.city=Reno&homeAddr.state=NV

I will attach a patch that contains modifications to the InjectionUtils class to support this behavior. In addition, the patch contains some unit test modifications the ensure more complex recursions of nested beans are taken care of. Note that no JAXRS* systests were harmed in the making of this patch, they all passed successfully.

The only notation change to the parameter format is the addition of the '.' to the name, which is the trigger that tells the code to assume a nested bean. Since this change is isolated to the injection processing logic, the capability works for Query, Form, Matrix, and Path parameter types. With that said, my functional testing has focused on query parameters, although I did change the unit tests for all for types to exercise the new capability.

When dealing with nested beans and lists things get a bit more complicated. Since the code doesn't introduce an indexing notation, there are a few rules that the consumer needs to be aware of. First, you can't inject list items into nested beans that are contained within a list themselves. Take the following bean class as an example:

class RecursiveBean
{ 
    String s;
    Integer i;
    List<String> sList;
    List<RecursiveBean> bList;
}

The following would be fine:

/getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested

You would end up with 1 top level bean with s='top' containing a sList with 2 items, and a bList with 2 nested beans both with s='nested'. The following case however won't work:

/getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested&bList.sList=nestedList1&bList.sList=nestedList2

The main reason it won't work is that you don't know where to inject 'nestedList1' and 'nestedList2', do they both go to the first, or should they be split up between the 2 nested beans. As such, if a nested list of this type is encountered, the values are simply not injected at all.

The second nuance to be aware of is that nested beans contained within a list must have their parameters set in the correct order, and not sparsely populated. Using the class defined in the previous example consider the following query:

/getBean?bList.s=nested1&bList.i=1&bList.s=nested2&bList.i=2

This is a valid query that creates 2 nested beans within bList, the first with s=nested1, i=1, and the second with s=nested2, i=2. Now imagine you wanted 2 nested beans with 'i' set the same as above, but the first not having 's' set at all. If you tried:

/getBean?bList.i=1&bList.s=nested2&bList.i=2

You would end up with the first bean having s=nested2 instead of being blank :(

I don't think the limitations that I mention represent common everyday use cases, however its worth pointing them out so folks don't hit them unexpectedly.

I hope you will consider folding this patch into the product with the next 2.2.x release, I think it will prove to be a powerful addition to the existing CXF extension.

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


[jira] Updated: (CXF-2153) Support nested parameter injection into beans

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

Craig Muchinsky updated CXF-2153:
---------------------------------

    Fix Version/s:     (was: 2.2.1)

> Support nested parameter injection into beans
> ---------------------------------------------
>
>                 Key: CXF-2153
>                 URL: https://issues.apache.org/jira/browse/CXF-2153
>             Project: CXF
>          Issue Type: Improvement
>          Components: REST
>    Affects Versions: 2.2.1
>            Reporter: Craig Muchinsky
>         Attachments: nestedbeans5.patch
>
>
> The current CXF extension for handling parameter injection into beans does not handle the case where you want to set values on beans that are within other beans. Take the following simple example:
> class Name 
> { 
>     String first; 
>     String last; 
> } 
> class Address 
> { 
>     String city; 
>     String state; 
> } 
> class Person 
> { 
>     Name legalName; 
>     Address homeAddr; 
>     String race; 
>     String sex; 
>     Date birthDate; 
> } 
> class MyService 
> { 
>     @GET 
>     @Path("/getPerson") 
>     Person getPerson(@QueryParam("") Person person); 
> } 
> I would like to be able to pass something like: 
> /getPerson?sex=M&legalName.first=John&legalName.last=Doe&homeAddr.city=Reno&homeAddr.state=NV
> I will attach a patch that contains modifications to the InjectionUtils class to support this behavior. In addition, the patch contains some unit test modifications the ensure more complex recursions of nested beans are taken care of. Note that no JAXRS* systests were harmed in the making of this patch, they all passed successfully.
> The only notation change to the parameter format is the addition of the '.' to the name, which is the trigger that tells the code to assume a nested bean. Since this change is isolated to the injection processing logic, the capability works for Query, Form, Matrix, and Path parameter types. With that said, my functional testing has focused on query parameters, although I did change the unit tests for all for types to exercise the new capability.
> When dealing with nested beans and lists things get a bit more complicated. Since the code doesn't introduce an indexing notation, there are a few rules that the consumer needs to be aware of. First, you can't inject list items into nested beans that are contained within a list themselves. Take the following bean class as an example:
> class RecursiveBean
> { 
>     String s;
>     Integer i;
>     List<String> sList;
>     List<RecursiveBean> bList;
> }
> The following would be fine:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested
> You would end up with 1 top level bean with s='top' containing a sList with 2 items, and a bList with 2 nested beans both with s='nested'. The following case however won't work:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested&bList.sList=nestedList1&bList.sList=nestedList2
> The main reason it won't work is that you don't know where to inject 'nestedList1' and 'nestedList2', do they both go to the first, or should they be split up between the 2 nested beans. As such, if a nested list of this type is encountered, the values are simply not injected at all.
> The second nuance to be aware of is that nested beans contained within a list must have their parameters set in the correct order, and not sparsely populated. Using the class defined in the previous example consider the following query:
> /getBean?bList.s=nested1&bList.i=1&bList.s=nested2&bList.i=2
> This is a valid query that creates 2 nested beans within bList, the first with s=nested1, i=1, and the second with s=nested2, i=2. Now imagine you wanted 2 nested beans with 'i' set the same as above, but the first not having 's' set at all. If you tried:
> /getBean?bList.i=1&bList.s=nested2&bList.i=2
> You would end up with the first bean having s=nested2 instead of being blank :(
> I don't think the limitations that I mention represent common everyday use cases, however its worth pointing them out so folks don't hit them unexpectedly.
> I hope you will consider folding this patch into the product with the next 2.2.x release, I think it will prove to be a powerful addition to the existing CXF extension.

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


[jira] Updated: (CXF-2153) Support nested parameter injection into beans

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

Craig Muchinsky updated CXF-2153:
---------------------------------

    Attachment: nestedbeans5.patch

> Support nested parameter injection into beans
> ---------------------------------------------
>
>                 Key: CXF-2153
>                 URL: https://issues.apache.org/jira/browse/CXF-2153
>             Project: CXF
>          Issue Type: Improvement
>          Components: REST
>    Affects Versions: 2.2.1
>            Reporter: Craig Muchinsky
>             Fix For: 2.2.1
>
>         Attachments: nestedbeans5.patch
>
>
> The current CXF extension for handling parameter injection into beans does not handle the case where you want to set values on beans that are within other beans. Take the following simple example:
> class Name 
> { 
>     String first; 
>     String last; 
> } 
> class Address 
> { 
>     String city; 
>     String state; 
> } 
> class Person 
> { 
>     Name legalName; 
>     Address homeAddr; 
>     String race; 
>     String sex; 
>     Date birthDate; 
> } 
> class MyService 
> { 
>     @GET 
>     @Path("/getPerson") 
>     Person getPerson(@QueryParam("") Person person); 
> } 
> I would like to be able to pass something like: 
> /getPerson?sex=M&legalName.first=John&legalName.last=Doe&homeAddr.city=Reno&homeAddr.state=NV
> I will attach a patch that contains modifications to the InjectionUtils class to support this behavior. In addition, the patch contains some unit test modifications the ensure more complex recursions of nested beans are taken care of. Note that no JAXRS* systests were harmed in the making of this patch, they all passed successfully.
> The only notation change to the parameter format is the addition of the '.' to the name, which is the trigger that tells the code to assume a nested bean. Since this change is isolated to the injection processing logic, the capability works for Query, Form, Matrix, and Path parameter types. With that said, my functional testing has focused on query parameters, although I did change the unit tests for all for types to exercise the new capability.
> When dealing with nested beans and lists things get a bit more complicated. Since the code doesn't introduce an indexing notation, there are a few rules that the consumer needs to be aware of. First, you can't inject list items into nested beans that are contained within a list themselves. Take the following bean class as an example:
> class RecursiveBean
> { 
>     String s;
>     Integer i;
>     List<String> sList;
>     List<RecursiveBean> bList;
> }
> The following would be fine:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested
> You would end up with 1 top level bean with s='top' containing a sList with 2 items, and a bList with 2 nested beans both with s='nested'. The following case however won't work:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested&bList.sList=nestedList1&bList.sList=nestedList2
> The main reason it won't work is that you don't know where to inject 'nestedList1' and 'nestedList2', do they both go to the first, or should they be split up between the 2 nested beans. As such, if a nested list of this type is encountered, the values are simply not injected at all.
> The second nuance to be aware of is that nested beans contained within a list must have their parameters set in the correct order, and not sparsely populated. Using the class defined in the previous example consider the following query:
> /getBean?bList.s=nested1&bList.i=1&bList.s=nested2&bList.i=2
> This is a valid query that creates 2 nested beans within bList, the first with s=nested1, i=1, and the second with s=nested2, i=2. Now imagine you wanted 2 nested beans with 'i' set the same as above, but the first not having 's' set at all. If you tried:
> /getBean?bList.i=1&bList.s=nested2&bList.i=2
> You would end up with the first bean having s=nested2 instead of being blank :(
> I don't think the limitations that I mention represent common everyday use cases, however its worth pointing them out so folks don't hit them unexpectedly.
> I hope you will consider folding this patch into the product with the next 2.2.x release, I think it will prove to be a powerful addition to the existing CXF extension.

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


[jira] Resolved: (CXF-2153) Support nested parameter injection into beans

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

Sergey Beryozkin resolved CXF-2153.
-----------------------------------

       Resolution: Fixed
    Fix Version/s: 2.2.1

Hi Craig - patch applied, many thanks. I did one or two cosmetic updates. 
I found the code be very precise and solid. I tried to collapse handleBean and processValues() into a single (handleBean()), but couldn't figure out the obvious way to do it :-), may be we can figure out something later on...

By the way, thanks for documenting the use cases in this JIRA - would you be interested in creating a little subsection here : http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-DealingwithParameters, by extracting the existing description of the beans extension and augmenting it a bit with the description of the common types of queries people would be able to do using a '.' separator ? Say using Queries or Matrixes... If yes then we can ask Dan to grant you the editing rights





> Support nested parameter injection into beans
> ---------------------------------------------
>
>                 Key: CXF-2153
>                 URL: https://issues.apache.org/jira/browse/CXF-2153
>             Project: CXF
>          Issue Type: Improvement
>          Components: REST
>    Affects Versions: 2.2.1
>            Reporter: Craig Muchinsky
>            Assignee: Sergey Beryozkin
>             Fix For: 2.2.1
>
>         Attachments: nestedbeans5.patch
>
>
> The current CXF extension for handling parameter injection into beans does not handle the case where you want to set values on beans that are within other beans. Take the following simple example:
> class Name 
> { 
>     String first; 
>     String last; 
> } 
> class Address 
> { 
>     String city; 
>     String state; 
> } 
> class Person 
> { 
>     Name legalName; 
>     Address homeAddr; 
>     String race; 
>     String sex; 
>     Date birthDate; 
> } 
> class MyService 
> { 
>     @GET 
>     @Path("/getPerson") 
>     Person getPerson(@QueryParam("") Person person); 
> } 
> I would like to be able to pass something like: 
> /getPerson?sex=M&legalName.first=John&legalName.last=Doe&homeAddr.city=Reno&homeAddr.state=NV
> I will attach a patch that contains modifications to the InjectionUtils class to support this behavior. In addition, the patch contains some unit test modifications the ensure more complex recursions of nested beans are taken care of. Note that no JAXRS* systests were harmed in the making of this patch, they all passed successfully.
> The only notation change to the parameter format is the addition of the '.' to the name, which is the trigger that tells the code to assume a nested bean. Since this change is isolated to the injection processing logic, the capability works for Query, Form, Matrix, and Path parameter types. With that said, my functional testing has focused on query parameters, although I did change the unit tests for all for types to exercise the new capability.
> When dealing with nested beans and lists things get a bit more complicated. Since the code doesn't introduce an indexing notation, there are a few rules that the consumer needs to be aware of. First, you can't inject list items into nested beans that are contained within a list themselves. Take the following bean class as an example:
> class RecursiveBean
> { 
>     String s;
>     Integer i;
>     List<String> sList;
>     List<RecursiveBean> bList;
> }
> The following would be fine:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested
> You would end up with 1 top level bean with s='top' containing a sList with 2 items, and a bList with 2 nested beans both with s='nested'. The following case however won't work:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested&bList.sList=nestedList1&bList.sList=nestedList2
> The main reason it won't work is that you don't know where to inject 'nestedList1' and 'nestedList2', do they both go to the first, or should they be split up between the 2 nested beans. As such, if a nested list of this type is encountered, the values are simply not injected at all.
> The second nuance to be aware of is that nested beans contained within a list must have their parameters set in the correct order, and not sparsely populated. Using the class defined in the previous example consider the following query:
> /getBean?bList.s=nested1&bList.i=1&bList.s=nested2&bList.i=2
> This is a valid query that creates 2 nested beans within bList, the first with s=nested1, i=1, and the second with s=nested2, i=2. Now imagine you wanted 2 nested beans with 'i' set the same as above, but the first not having 's' set at all. If you tried:
> /getBean?bList.i=1&bList.s=nested2&bList.i=2
> You would end up with the first bean having s=nested2 instead of being blank :(
> I don't think the limitations that I mention represent common everyday use cases, however its worth pointing them out so folks don't hit them unexpectedly.
> I hope you will consider folding this patch into the product with the next 2.2.x release, I think it will prove to be a powerful addition to the existing CXF extension.

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


[jira] Assigned: (CXF-2153) Support nested parameter injection into beans

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

Sergey Beryozkin reassigned CXF-2153:
-------------------------------------

    Assignee: Sergey Beryozkin

> Support nested parameter injection into beans
> ---------------------------------------------
>
>                 Key: CXF-2153
>                 URL: https://issues.apache.org/jira/browse/CXF-2153
>             Project: CXF
>          Issue Type: Improvement
>          Components: REST
>    Affects Versions: 2.2.1
>            Reporter: Craig Muchinsky
>            Assignee: Sergey Beryozkin
>         Attachments: nestedbeans5.patch
>
>
> The current CXF extension for handling parameter injection into beans does not handle the case where you want to set values on beans that are within other beans. Take the following simple example:
> class Name 
> { 
>     String first; 
>     String last; 
> } 
> class Address 
> { 
>     String city; 
>     String state; 
> } 
> class Person 
> { 
>     Name legalName; 
>     Address homeAddr; 
>     String race; 
>     String sex; 
>     Date birthDate; 
> } 
> class MyService 
> { 
>     @GET 
>     @Path("/getPerson") 
>     Person getPerson(@QueryParam("") Person person); 
> } 
> I would like to be able to pass something like: 
> /getPerson?sex=M&legalName.first=John&legalName.last=Doe&homeAddr.city=Reno&homeAddr.state=NV
> I will attach a patch that contains modifications to the InjectionUtils class to support this behavior. In addition, the patch contains some unit test modifications the ensure more complex recursions of nested beans are taken care of. Note that no JAXRS* systests were harmed in the making of this patch, they all passed successfully.
> The only notation change to the parameter format is the addition of the '.' to the name, which is the trigger that tells the code to assume a nested bean. Since this change is isolated to the injection processing logic, the capability works for Query, Form, Matrix, and Path parameter types. With that said, my functional testing has focused on query parameters, although I did change the unit tests for all for types to exercise the new capability.
> When dealing with nested beans and lists things get a bit more complicated. Since the code doesn't introduce an indexing notation, there are a few rules that the consumer needs to be aware of. First, you can't inject list items into nested beans that are contained within a list themselves. Take the following bean class as an example:
> class RecursiveBean
> { 
>     String s;
>     Integer i;
>     List<String> sList;
>     List<RecursiveBean> bList;
> }
> The following would be fine:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested
> You would end up with 1 top level bean with s='top' containing a sList with 2 items, and a bList with 2 nested beans both with s='nested'. The following case however won't work:
> /getBean?s=top&sList=toplist1&sList=toplist2&bList.s=nested&bList.s=nested&bList.sList=nestedList1&bList.sList=nestedList2
> The main reason it won't work is that you don't know where to inject 'nestedList1' and 'nestedList2', do they both go to the first, or should they be split up between the 2 nested beans. As such, if a nested list of this type is encountered, the values are simply not injected at all.
> The second nuance to be aware of is that nested beans contained within a list must have their parameters set in the correct order, and not sparsely populated. Using the class defined in the previous example consider the following query:
> /getBean?bList.s=nested1&bList.i=1&bList.s=nested2&bList.i=2
> This is a valid query that creates 2 nested beans within bList, the first with s=nested1, i=1, and the second with s=nested2, i=2. Now imagine you wanted 2 nested beans with 'i' set the same as above, but the first not having 's' set at all. If you tried:
> /getBean?bList.i=1&bList.s=nested2&bList.i=2
> You would end up with the first bean having s=nested2 instead of being blank :(
> I don't think the limitations that I mention represent common everyday use cases, however its worth pointing them out so folks don't hit them unexpectedly.
> I hope you will consider folding this patch into the product with the next 2.2.x release, I think it will prove to be a powerful addition to the existing CXF extension.

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