This discussion is archived
4 Replies Latest reply: Mar 9, 2010 8:43 AM by 843793 RSS

How to refer to genericized interface

843793 Newbie
Currently Being Moderated
Hi,

I have the following interface:
package org.tbiq.gwt.tools.rpcrequest.server;

import org.tbiq.gwt.tools.rpcrequest.browser.RpcRequest;
import org.tbiq.gwt.tools.rpcrequest.browser.RpcRequestException;
import org.tbiq.gwt.tools.rpcrequest.browser.RpcRequestService;
import org.tbiq.gwt.tools.rpcrequest.browser.RpcResponse;

public interface RpcRequestHandler<ReqT extends RpcRequest<ResT>, ResT extends RpcResponse>
{
public boolean isCompatibleWith(Class<ReqT> rpcRequestClass);

public ResT execute(ReqT rpcRequest)
throws RpcRequestException;
}
I also have a dummy implementation of this interface:
package org.tbiq.gwt.tools.rpcrequest.server;

import org.tbiq.gwt.tools.rpcrequest.browser.DummyRpcRequest;
import org.tbiq.gwt.tools.rpcrequest.browser.DummyRpcResponse;
import org.tbiq.gwt.tools.rpcrequest.browser.RpcRequestException;

public class NewDummyRequestHandler
implements RpcRequestHandler<DummyRpcRequest, DummyRpcResponse>
{
@Override
public DummyRpcResponse execute(DummyRpcRequest rpcRequest)
throws RpcRequestException
{
// TODO Auto-generated method stub
return null;
}

@Override
public boolean isCompatibleWith(Class<DummyRpcRequest> rpcRequestClass)
{
if (DummyRpcRequest.class == rpcRequestClass)
{
return true;
}
return false;
}
}
This interface refers to 2 dummy objects DummyRpcRequest and DummyRpcResponse. There is nothing special about them. They are just regular beans that implement marker interfaces (RpcResponse and RpcRequest<T extends RpcResponse>).
DummyRpcResponse:
package org.tbiq.gwt.tools.rpcrequest.browser;

@SuppressWarnings("serial")
public class DummyRpcResponse
implements RpcResponse
{
}
DummyRpcRequest:
package org.tbiq.gwt.tools.rpcrequest.browser;

@SuppressWarnings("serial")
public class DummyRpcRequest
implements RpcRequest<DummyRpcResponse>
{
}
Somewhere else, I have a class that implements some other interface. Part of implementing that interface is this method:
@Override
public <T extends RpcResponse> T execute(RpcRequest<T> rpcRequest)
throws RpcRequestException
{
RpcRequestHandler<??????> handler = new NewDummyRequestHandler();

return handler.execute(rpcRequest);
}
So, the '?????' is my question. How do I refer to the handler such that it compiles. Right now, now matter what I try in that line, the handler.execute(rpcRequest) doesn't compile.

Also, it's possible that I messed up my RpcRequestHandler interface and defined it in a wrong way (as far as generics are concerned). I am not sure.

Any help would be much appreciated!

Thanks,
Yaakov.

P.S. The code in the last method is obviously for testing only. I am planning to have a Map of those handlers and choose the handler dynamically based on the type of the RpcRequest that is passed into the execute method.

Edited by: ychaikin on Feb 23, 2010 1:10 PM
  • 1. Re: How to refer to genericized interface
    843793 Newbie
    Currently Being Moderated
    Couple things:

    To match the RPCRequestHandler interface:
    RpcRequestHandler<ReqT extends RpcRequest<ResT>, ResT extends RpcResponse>
    are we assuming DummyRpcRequest is defined like this:
    public class DummyRpcRequest<X> ...
    where X is a subclass of (or implements, dunno how it works) RpcResponse.

    Anyway ... It's been ages since I've delved into generics, and from memory I get the feeling this might fail, because the type "T" can't actually be inferred, but try this:
         @Override
         public <E extends RpcRequest<T>, T extends RpcResponse> T execute(E rpcRequest)
         throws RpcRequestException
         {
              RpcRequestHandler<E, T> handler = new NewDummyRequestHandler<E, T>();
              return handler.execute(rpcRequest);
         }
  • 2. Re: How to refer to genericized interface
    843793 Newbie
    Currently Being Moderated
    Had a play round some more with this to refresh my knowledge, and understand exactly where you're coming from

    I don't know what your RpcRequest and RpcResponse interfaces look like - although since your concrete implementations DummyRpcRequest and DummyRpcResponse don't implement any methods, I guess that means that the two interfaces are blank.

    The fact that the RpcRequest takes a parameter of a subclass of RpcResponse, though, implies that there's some sort of relationship there. Perhaps, in future, you intend to have a method sig in RpcRequest that say, returns a subclass of (the type of RpcResponse you created the concrete implementation of RpcRequest with). It's hard to offer more suggestions without knowing exactly what you intend with this code.

    A handler takes a RpcRequest<RpcResponse>, runs its execute method, and somehow (depending on implementation) returns an RpcResponse.

    So I tested some code which I guess summarises your situation, and which works okay - if you want, you can blat this all into a file Test.java and compile/run it in textpad.
    interface Response {
         String message();
    }
    
    class SpecificResponse implements Response {
         public String message() { return "Why hello there!"; }
    }
    
    interface Request<E extends Response> {}
    
    /* This Request subclass stores a canned, fixed Response object. */
    class StoredResponseRequest<E extends Response> implements Request<E> {
         private E myResponse;
    
         public StoredResponseRequest(E useThis) {
              myResponse = useThis;
         }
    
          public E getStoredResponse() {
              return myResponse;
         }
    }
    
    /* A handler <B, A> is able to take in a B (extends Request<A>), and return an A. */
    interface Handler<B extends Request<A>, A extends Response> {
         public A execute(B request);
    }
    
    /* A HandlerForStoredResponseRequests works by assuming that all the Request<A>s it gets passed are, in fact,
         StoredResponseRequest<A>s. It therefore extracts the necessary A from the object and returns it.  */
    class HandlerForStoredResponseRequests <B extends Request<A>, A extends Response> implements Handler<B, A> {
         public A execute(B sreq) {
              return ((StoredResponseRequest<A>)sreq).getStoredResponse();
         }
    }
    
    
    class Test {
         public static void main(String[] argz) {
              Request<Response> request = new StoredResponseRequest<Response>(new SpecificResponse());
              System.out.println( execute(request).message() );
    
         }
    
         public static <T extends Request<E>, E extends Response> E execute(T request) {
              Handler<T, E> stuffHandler = new HandlerForStoredResponseRequests<T, E>();
              return stuffHandler.execute(request);
         }
    }
  • 3. Re: How to refer to genericized interface
    843793 Newbie
    Currently Being Moderated
    ychaikin wrote:
    @Override
    public <T extends RpcResponse> T execute(RpcRequest<T> rpcRequest)
    throws RpcRequestException
    {
    RpcRequestHandler<??????> handler = new NewDummyRequestHandler();
    
    return handler.execute(rpcRequest);
    }
    So, the '?????' is my question. How do I refer to the handler such that it compiles. Right now, now matter what I try in that line, the handler.execute(rpcRequest) doesn't compile.
    The long and the short of it is that handler is a handler for (and thus execute only accepts subtypes of) DummyRpcRequests yet rpcRequest may be any kind of RpcRequest. One or the other has to change.

    With kind regards
    Ben
  • 4. Re: How to refer to genericized interface
    843793 Newbie
    Currently Being Moderated
    Here is what I ended up with:
    public <RpcRequestT extends RpcRequest<RpcResponseT>, RpcResponseT extends RpcResponse> RpcResponseT execute(RpcRequestT rpcRequest)
        throws RpcServiceException
      {
        // Retrieve RPC request handler for this RPC request
        RpcRequestHandler<RpcRequestT, RpcResponseT> handler = (RpcRequestHandler<RpcRequestT, RpcResponseT>) rpcRequestHandlerRegistry
          .getHandlerFor(rpcRequest.getClass());
    where getHandler signature is like this:
    public RpcRequestHandler<? extends RpcRequest<? extends RpcResponse>, ? extends RpcResponse> getHandlerFor(Class<?> rpcRequestClassType);
    Thanks for all the suggestions though.

    Yaakov.