Gah,
You are right, I thought I tried that already and had it fail to
compile. That will teach me for rushing. It make sense as the type is
erased at run time. On top of that you can also do the following to
signal that you really meant to make this cast:
@SuppressWarnings("unchecked") ResponseBuilder<V> vThis
= (ResponseBuilder<V>)this;
To suppress the -Xlint compiler warnings you might see otherwise. You
can't do that directly on the return statement; but you could on the method.
Gerard
On 10/11/2009 16:57, Paul Sandoz wrote:
> Hi,
>
> It's a bit of a hack but following also works i.e. one can recast
> rather than wrap state.
>
> Paul.
>
> public class Main {
>
> public static class Response<T> {
>
> private final T entity;
>
> private Response(T entity) {
> this.entity = entity;
> }
>
> public T getEntity() {
> return entity;
> }
>
> public static <T> ResponseBuilder<T> start() {
> return new ResponseBuilder<T>();
> }
>
> public static class ResponseBuilder<T> {
> private T entity;
>
> public ResponseBuilder<T> header(String name, String value) {
> return this;
> }
>
> public <V> ResponseBuilder<V> entity(V ent) {
> ResponseBuilder<V> vThis = (ResponseBuilder<V>)this;
> vThis.entity = ent;
> return vThis;
> }
>
> public Response<T> build() {
> return new Response<T>(entity);
> }
> }
>
> /**
> * @param args the command line arguments
> */
> public static void main(String[] args) {
>
> Response<String> stringResponse = Response.start()
> .entity(1)
> .entity("String")
> .header("Content-Type", "cheese")
> .build();
> }
> }
> }
>
>
> On Nov 10, 2009, at 5:40 PM, gerard davison wrote:
>
>>
>>
>>
>>>
>>>> The other solution that occurs to me and I have seen often used is
>>>> to not bind the type in the builder until it is specified see
>>>> below. The trick is to create a new instance of ResponseBuilder
>>>> when we need to bind in the type; and pass in the internal state.
>>>> Until the call to entity(...) the generic parameter T is unbound.
>>>> (I have included the GenericEntity case; but I am not sure it would
>>>> be required if the interface is properly generic).
>>>>
>>> This looks like an interesting approach. Its too late now to do
>>> anything for 1.1 but I think we should look at this for 2.0. Would
>>> you create an issue at
>>> https://jsr311.dev.java.net/servlets/ProjectIssues and include this
>>> suggestion so we can track it when we make a start on the next
>>> version of the API.
>>
>> Done,
>>
>> https://jsr311.dev.java.net/issues/show_bug.cgi?id=83
>>
>> Gerard
>>
>>>
>>> Thanks,
>>> Marc.
>>>
>>>
>>>> // Generified Response
>>>> ~
>>>> public class Response<T> {
>>>>
>>>> static class GListString extends GenericEntity<List<String>> {
>>>> public GListString(List<String> list) {
>>>> super(list);
>>>> }
>>>> }
>>>>
>>>> private final T entity;
>>>>
>>>> private Response(T entity) {
>>>> this.entity = entity;
>>>> }
>>>>
>>>> public T getEntity() {
>>>> return entity;
>>>> }
>>>> public static <T> ResponseBuilder<T> start() {
>>>> return new ResponseBuilder<T>("Some State");
>>>> }
>>>> public static class ResponseBuilder<T> {
>>>>
>>>> private Object state;
>>>> private Type type;
>>>> private T entity;
>>>>
>>>> public ResponseBuilder(Object state) {
>>>> this.state = state;
>>>> }
>>>>
>>>> public ResponseBuilder(Object state, Type type, T object) {
>>>> this(state);
>>>> this.type = type;
>>>> this.entity = object;
>>>> }
>>>> public ResponseBuilder<T> header(String name,
>>>> String value) {
>>>> return this;
>>>> }
>>>>
>>>>
>>>> public <T, K extends GenericEntity<T>> ResponseBuilder<T>
>>>> entity(K ent) {
>>>> return new ResponseBuilder<T>(state, ent.getType(),
>>>> ent.getEntity());
>>>> }
>>>>
>>>> public <T> ResponseBuilder<T> entity(T ent) {
>>>> return new ResponseBuilder<T>(state, ent.getClass(), ent);
>>>> }
>>>>
>>>> public Response<T> build() {
>>>> return new Response<T>(entity);
>>>> }
>>>>
>>>> }
>>>>
>>>>
>>>> public static void main(String[] args) {
>>>>
>>>> List<String> list = new ArrayList<String>();
>>>> GListString genericList =
>>>> new GListString(list);
>>>>
>>>> Response<List<String>> response = Response
>>>> .start()
>>>> .header("Content-Type", "fudge")
>>>> .entity(list)
>>>> .build();
>>>>
>>>> // Using generic entity
>>>> //
>>>>
>>>> Response<List<String>> genericResponse = Response
>>>> .start()
>>>> .header("Content-Type", "fudge")
>>>> .entity(genericList)
>>>> .build();
>>>>
>>>> // String example
>>>> //
>>>> Response<String> stringResponse = Response
>>>> .start() // ResponseBuilder<?>
>>>> .entity("String") // ResponseBuilder<String>
>>>> .header("Content-Type", "cheese") // ResponseBuilder<String>
>>>> .build();
>>>> }
>>>>
>>>> }
>>>>
>>>>
>>>>>
>>>>> Unfortunately it is too late to make changes to JAX-RS 1.1. I
>>>>> could add something to Jersey in the interim.
>>>>
>>>> Damm, I figured as much. Do I need to raise this as an issue for
>>>> this for the next release. I guess I am going to have to wait until
>>>> 2.x for this. As to a workaround, it would be useful the WADL
>>>> issue, I guess it could as simple as a generic subtype of these
>>>> classes. I guess I will log that with the root issue which stated
>>>> this discussion, hopefully I will have this done in a few days.
>>>>
>>>> Cheers,
>>>>
>>>> Gerard
>>>>
>>>>>
>>>>> Paul.
>>>>>
>>>>>
>>>>> public class Main {
>>>>>
>>>>> public static class Response<T> {
>>>>>
>>>>> private final T entity;
>>>>>
>>>>> private Response(T entity) {
>>>>> this.entity = entity;
>>>>> }
>>>>>
>>>>> public T getEntity() {
>>>>> return entity;
>>>>> }
>>>>>
>>>>> public static class ResponseBuilder<T> {
>>>>> private T entity;
>>>>>
>>>>> public ResponseBuilder<T> entity(T entity) {
>>>>> this.entity = entity;
>>>>> return this;
>>>>> }
>>>>>
>>>>> public Response<T> build() {
>>>>> return new Response<T>(entity);
>>>>> }
>>>>>
>>>>> static protected <T> ResponseBuilder<T> newInstance() {
>>>>> return
>>>>> RuntimeDelegate.getInstance().<T>createResponseBuilder();
>>>>> }
>>>>> }
>>>>>
>>>>> static public <T> ResponseBuilder<T> start() {
>>>>> return new ResponseBuilder<T>();
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>> public static class RuntimeDelegate {
>>>>> public static RuntimeDelegate getInstance() {
>>>>> return new RuntimeDelegate();
>>>>> }
>>>>>
>>>>> public <T> Response.ResponseBuilder<T>
>>>>> createResponseBuilder() {
>>>>> return new Response.ResponseBuilder<T>();
>>>>> }
>>>>> }
>>>>>
>>>>> /**
>>>>> * @param args the command line arguments
>>>>> */
>>>>> public static void main(String[] args) {
>>>>> Response<String> r =
>>>>> Response.<String>start().entity("xx").build();
>>>>>
>>>>> String e = r.getEntity();
>>>>> System.out.println(e);
>>>>> }
>>>>> }
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>
>>>> --
>>>> Gerard Davison | Senior Principal Software Engineer | +44 118 924 5095
>>>> Oracle JDeveloper Web Service Tooling Development
>>>> Oracle Corporation UK Ltd is a company incorporated in England &
>>>> Wales.
>>>> Company Reg. No. 1782505.
>>>> Reg. office: Oracle Parkway, Thames Valley Park, Reading RG6 1RA.
>>>>
>>>> Blog http://kingsfleet.blogspot.com
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>> --
>> Gerard Davison | Senior Principal Software Engineer | +44 118 924 5095
>> Oracle JDeveloper Web Service Tooling Development
>> Oracle Corporation UK Ltd is a company incorporated in England & Wales.
>> Company Reg. No. 1782505.
>> Reg. office: Oracle Parkway, Thames Valley Park, Reading RG6 1RA.
>>
>> Blog http://kingsfleet.blogspot.com
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
--
Gerard Davison | Senior Principal Software Engineer | +44 118 924 5095
Oracle JDeveloper Web Service Tooling Development
Oracle Corporation UK Ltd is a company incorporated in England & Wales.
Company Reg. No. 1782505.
Reg. office: Oracle Parkway, Thames Valley Park, Reading RG6 1RA.
Blog http://kingsfleet.blogspot.com