Using Interface Types and Abstract Classes
The API is defined the same way as in the preceeding use case.
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 ); } }
Since Param is an interface, the runtime system cannot create instances of this type without further information.
We use the concrete attribute of the @XmlRpc annotation to tell the Delight runtime-system what concrete type to use to create instances of type Param.
In this case we use the concete class ParamImpl to create instances of type Param (note that ParamImpl has to be a Convertable and also has to implement Param):
@XmlRpc( type=Type.STRING, concrete=ParamImpl.class ) public interface Param { public String printContent() { ... } } public class ParamImpl implements Param, Convertable<String> { public ParamImpl( String xmlRpcRepresentation ) { processXmlRpc( xmlRpcRepresentation ); } public String toXmlRpc() { return( createXmlRpcRep() ); } }
Client side
The client can be created and used without further actions to take. No factories to register. No configuration files to load. Just like a local call to the API.
Api remote_api = XmlRpc.createClient( Api.class, "handlerId", host, port ); Param p = remote_api.returnParam(); System.out.println( p.printContent() ); Param asParam = new ParamImpl(...); remote_api.passAsParameter( asParam ); ...
See also How to use own types in Collections an Maps.
Examples in source code: http://delight.opendfki.de/repos/trunk/XmlRpcDelight/src/examples/de/dfki/util/xmlrpc/examples/interfaces/