You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Chris Geer <ch...@cxtsoftware.com> on 2012/06/19 16:23:13 UTC

@ElementClass hint with List<> or Array

Is there a way to use the @ElementClass hint with returns that are List<>
or Arrays? I have a resource that I want the WADL to generate showing the
response element correctly and my methods return Response objects. On the
methods that return singular objects I can use @ElementClass( response =
Module.class) and the WADL will include the proper element in the response
section. I can't seem to get the same results with methods that return
List<String> or Module[]. I can define the Array one with @ElementClass(
response = Module[].class) but the element class in the WADL isn't present.
I can't even define the generic List approach.

Is there a way to handle this?

Examples:

This works great and the WADL includes the element.

@GET
@PATH("/module")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@ElementClass(response = Module.class)
public Response getModule() { ... }

This generates a WADL with a missing element tag

@GET
@PATH("/modules")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@ElementClass(response = Module[].class)
public Response getModules() { ... }

This just doesn't work at all since you can't get a class object from a
List like this (i.e. won't compile).

@GET
@PATH("/modules")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@ElementClass(response = List<Module>.class)
public Response getModules() { ... }

Module is a JAXB object that is generated from a schema.

Thanks,
Chris

Re: @ElementClass hint with List<> or Array

Posted by Sergey Beryozkin <sb...@gmail.com>.
I may have an idea how to solve it, rather than trying to get 
JAXBContext to generate a schema element/type for a collection wrapper, 
I can simply update the generated schema (available as DOMSource) and 
insert one extra element declaration...

Sergey
On 20/06/12 10:36, Sergey Beryozkin wrote:
> Hi Chris
>
> On 19/06/12 15:23, Chris Geer wrote:
>> Is there a way to use the @ElementClass hint with returns that are List<>
>> or Arrays? I have a resource that I want the WADL to generate showing the
>> response element correctly and my methods return Response objects. On the
>> methods that return singular objects I can use @ElementClass( response =
>> Module.class) and the WADL will include the proper element in the
>> response
>> section. I can't seem to get the same results with methods that return
>> List<String> or Module[]. I can define the Array one with @ElementClass(
>> response = Module[].class) but the element class in the WADL isn't
>> present.
>> I can't even define the generic List approach.
>>
>> Is there a way to handle this?
>
> Not at the moment. Usually I recommend adding simple collection wrappers
> which is better IMHO for a number of reasons, but I admit that explicit
> collections will always be there in the method signatures...
> The problem is how to get a JAXB compiler to generate a schema type and
> element representing a collection wrapper.
>
> For example, given a JAXB-annotated Module class, JAXB compiler will
> generate the schema element and type. Similarly with a basic Modules
> wrapper class. If we have List<Module>, the question is how to get the
> compiler to produce a scheme element with, say, "modules" name.
>
> If someone has an idea how to create a JAXBContext such that it
> generates a proper schema for collections then we can do. I can only
> think of using ASM to auto-generate such wrappers at the startup but it
> won't work in cases where JAXBElementProvider is used to configure a
> collection wrapper name
>
> Cheers, Sergey
>
>>
>> Examples:
>>
>> This works great and the WADL includes the element.
>>
>> @GET
>> @PATH("/module")
>> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
>> @ElementClass(response = Module.class)
>> public Response getModule() { ... }
>>
>> This generates a WADL with a missing element tag
>>
>> @GET
>> @PATH("/modules")
>> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
>> @ElementClass(response = Module[].class)
>> public Response getModules() { ... }
>>
>> This just doesn't work at all since you can't get a class object from a
>> List like this (i.e. won't compile).
>>
>> @GET
>> @PATH("/modules")
>> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
>> @ElementClass(response = List<Module>.class)
>> public Response getModules() { ... }
>>
>> Module is a JAXB object that is generated from a schema.
>>
>> Thanks,
>> Chris
>>
>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: @ElementClass hint with List<> or Array

Posted by Sergey Beryozkin <sb...@gmail.com>.
CC-ing to the users list
On 26/06/12 15:46, Sergey Beryozkin wrote:
> Hi
> On 20/06/12 15:50, Chris Geer wrote:
>> Sergey,
>>
>> On Wed, Jun 20, 2012 at 2:36 AM, Sergey Beryozkin <sberyozkin@gmail.com
>> <ma...@gmail.com>> wrote:
>>
>> Hi Chris
>>
>>
>> On 19/06/12 15:23, Chris Geer wrote:
>>
>> Is there a way to use the @ElementClass hint with returns that
>> are List<>
>> or Arrays? I have a resource that I want the WADL to generate
>> showing the
>> response element correctly and my methods return Response
>> objects. On the
>> methods that return singular objects I can use @ElementClass(
>> response =
>> Module.class) and the WADL will include the proper element in
>> the response
>> section. I can't seem to get the same results with methods that
>> return
>> List<String> or Module[]. I can define the Array one with
>> @ElementClass(
>> response = Module[].class) but the element class in the WADL
>> isn't present.
>> I can't even define the generic List approach.
>>
>> Is there a way to handle this?
>>
>>
>> Not at the moment. Usually I recommend adding simple collection
>> wrappers which is better IMHO for a number of reasons, but I admit
>> that explicit collections will always be there in the method
>> signatures...
>>
>>
>> I usually use wrappers as well, but it isn't ideal in all cases.
>
> I've prototyped some support for getting schema elements representing
> collection wrappers added to schemas generated by the JAXB compilers.
> I think it's a bit brittle and hence WADlGenerator can be configured to
> get this option disabled, with a new property 'supportCollections' set
> to false.
>
> XMLName annotation is needed to provide a hint to WADLGenerator, example:
> @GET
> @XMLName("{http://books}books")
> public Book[] getBooks();
>
>>
>> The problem is how to get a JAXB compiler to generate a schema type
>> and element representing a collection wrapper.
>>
>> For example, given a JAXB-annotated Module class, JAXB compiler will
>> generate the schema element and type. Similarly with a basic Modules
>> wrapper class. If we have List<Module>, the question is how to get
>> the compiler to produce a scheme element with, say, "modules" name.
>>
>> If someone has an idea how to create a JAXBContext such that it
>> generates a proper schema for collections then we can do. I can only
>> think of using ASM to auto-generate such wrappers at the startup but
>> it won't work in cases where JAXBElementProvider is used to
>> configure a collection wrapper name
>>
>>
>> On a side note, another things I noticed was it won't work if you try
>> and return primitive types like String. I guess the solution would be to
>> have wrapper types for primitives as well however there are cases where
>> dealing in just the primitive makes a lot of sense in JAX-RS services.
>> Is the only solution to use a wrapper?
>>
> A custom provider wrapping and unwrapping primitive types to/from XML
> payloads may be registered. However it won't be supported by WADLGenerator
>
> Cheers, Sergey
>>
>> Cheers, Sergey
>>
>>
>>
>> Examples:
>>
>> This works great and the WADL includes the element.
>>
>> @GET
>> @PATH("/module")
>> @Produces({MediaType.__APPLICATION_JSON, MediaType.APPLICATION_XML})
>> @ElementClass(response = Module.class)
>> public Response getModule() { ... }
>>
>> This generates a WADL with a missing element tag
>>
>> @GET
>> @PATH("/modules")
>> @Produces({MediaType.__APPLICATION_JSON, MediaType.APPLICATION_XML})
>> @ElementClass(response = Module[].class)
>> public Response getModules() { ... }
>>
>> This just doesn't work at all since you can't get a class object
>> from a
>> List like this (i.e. won't compile).
>>
>> @GET
>> @PATH("/modules")
>> @Produces({MediaType.__APPLICATION_JSON, MediaType.APPLICATION_XML})
>> @ElementClass(response = List<Module>.class)
>> public Response getModules() { ... }
>>
>> Module is a JAXB object that is generated from a schema.
>>
>> Thanks,
>> Chris
>>
>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com
>>
>>
>
>

Re: @ElementClass hint with List<> or Array

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Chris

On 19/06/12 15:23, Chris Geer wrote:
> Is there a way to use the @ElementClass hint with returns that are List<>
> or Arrays? I have a resource that I want the WADL to generate showing the
> response element correctly and my methods return Response objects. On the
> methods that return singular objects I can use @ElementClass( response =
> Module.class) and the WADL will include the proper element in the response
> section. I can't seem to get the same results with methods that return
> List<String>  or Module[]. I can define the Array one with @ElementClass(
> response = Module[].class) but the element class in the WADL isn't present.
> I can't even define the generic List approach.
>
> Is there a way to handle this?

Not at the moment. Usually I recommend adding simple collection wrappers 
which is better IMHO for a number of reasons, but I admit that explicit 
collections will always be there in the method signatures...
The problem is how to get a JAXB compiler to generate a schema type and 
element representing a collection wrapper.

For example, given a JAXB-annotated Module class, JAXB compiler will 
generate the schema element and type. Similarly with a basic Modules 
wrapper class. If we have List<Module>, the question is how to get the 
compiler to produce a scheme element with, say, "modules" name.

If someone has an idea how to create a JAXBContext such that it 
generates a proper schema for collections then we can do. I can only 
think of using ASM to auto-generate such wrappers at the startup but it 
won't work in cases where JAXBElementProvider is used to configure a 
collection wrapper name

Cheers, Sergey

>
> Examples:
>
> This works great and the WADL includes the element.
>
> @GET
> @PATH("/module")
> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
> @ElementClass(response = Module.class)
> public Response getModule() { ... }
>
> This generates a WADL with a missing element tag
>
> @GET
> @PATH("/modules")
> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
> @ElementClass(response = Module[].class)
> public Response getModules() { ... }
>
> This just doesn't work at all since you can't get a class object from a
> List like this (i.e. won't compile).
>
> @GET
> @PATH("/modules")
> @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
> @ElementClass(response = List<Module>.class)
> public Response getModules() { ... }
>
> Module is a JAXB object that is generated from a schema.
>
> Thanks,
> Chris
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com