wiki:ExampleUsingOwnConceteTypes

Version 6 (modified by lauer, 18 years ago) (diff)

--

Using own concete types

Special case: Using own types in Collections and Maps. Java's type erasure in action!

Server side

We want to use the type Param in our API. Normally, this will cause an error message. See how we can make this type XML-RPC compliant with only a few lines of code:

public interface Api
{
    Param returnParam();
    
    void passAsParameter( Param p );
}

public class Impl implements Api
{
    public Param returnParam() { return createParam( ... ); }
    
    void passAsParameter( Param p ) { doSomethingWith( p ); }
}

To use type Param, we have to make it XML-RPC compliant. We use java annotations and user-defined conversion operations to do this.

  • the @XmlRpc annotation declares that type Param uses XML-RPC type ARRAY as transport representation
  • The interface {{{Convertable}} declares what specific java type is used for transfer via XML-RPC
  • toXmlRpc converts an instance of type Param into its XML-RPC representation
  • the constructor creates an instance of type Param back from it's XML-RPC representation
@XmlRpc( type=Type.ARRAY )      
public class Param 
               implements Convertable<Collection<String>>
{
    public Param( Collection<String> xmlRpcRepresentation ) { ... }

    public Collection<String> toXmlRpc() { return ... }
}

Now our type ist XML-RPC compliant! We can register the implementation as usual...

WebServer xmlRpcServer = new WebServer( port );
xmlRpcServer.addHandler( "handlerId", XmlRpcHandlerFactory.createHandlerFor( new Impl() );
xmlRpcServer.start();

Client Side

Our client can be used without any extra statements:

Api remote_api = XmlRpc.createClient( Api.class, "handlerId", host, port );

Param p = remote_api.returnParam();

Param asParam = ...;
remote_api.passAsParameter( asParam );

...

Using own types in Collections and Maps

Collections, maps and arrays using the user-defined type as content can also be used out-of-the-box.

// WORKS!
public interface Api
{
    Map<String,Param> returnMyParamInMap();
    
    void passManyParams( Collection<Param> params );

    void passParamsInArray( Param[] params );
}

Client Side

Now remote clients can also use Collections and Maps containing own types:

Api remote_api = XmlRpc.createClient( Api.class, "handlerId", host, port );

Map<String,Param> map = remote_api.returnMyParamInMap();
for( Param p : map.values() )
{
  ...
}

remote_api.passManyParams( Collections.asList( new Param[]{new Param(), new Param()} ) );
...

Examples in source code: http://delight.opendfki.de/repos/trunk/XmlRpcDelight/src/examples/de/dfki/util/xmlrpc/examples/concrete_types/