//
// $Id: InvocationProvider.java,v 1.6 2001/10/11 04:07:53 mdb Exp $
package com.threerings.presents.server;
import com.samskivert.util.StringUtil;
import com.threerings.presents.Log;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.data.InvocationObject;
import com.threerings.presents.dobj.MessageEvent;
/**
* Invocation providers should extend this class when implementing
* invocation services. Because the service procedures are identified by
* strings and the methods that are invoked are looked up via reflection,
* the derived class doesn't override or implement any particular method.
* However, the procedure names are still restricted. For example, a
* procedure identified by the name Tell would result in the
* invocation of a method named handleTellRequest. The
* arguments to that method would be defined by the arguments that
* accompanied the Tell invocation request along with the
* client object of the client that made the request. Specifically:
*
*
* // client makes request
* Object[] args = new Object[] { "one", new Integer(2) };
* invmgr.invoke(MODULE, "Test", args, rsptarget);
*
* // provider registered for MODULE should look like:
* public class TestProvider extends InvocationProvider
* {
* public void handleTestRequest (ClientObject source, int invid,
* String one, int two)
* {
* // ...
* }
* }
*
*
* If the arguments do not match, a reflection error will happen when
* trying to invoke the method and the whole request will fail.
*
* Invocation procedures must also package up their response in a
* particular way which is through the use of the
* sendResponse methods. These take a response identifier
* (which determines the name of the method that will be invoked on the
* response target object provided in the client) and a variable number of
* arguments. If a response was created with the identifier
* TellFailed, that would result in the method
* handleTellFailed being invoked on the response target
* object in the client. Again the arguments much match exactly and follow
* the reflection rules for automatic conversion of primitive types
* (supply an Integer object for int params,
* etc.).
*/
public class InvocationProvider
{
/**
* Delivers an invocation response properly configured with the
* supplied name and no arguments.
*/
protected void sendResponse (ClientObject source, int invid, String name)
{
deliverResponse(source, new Object[] { name, new Integer(invid) });
}
/**
* Delivers an invocation response properly configured with the
* supplied name and single argument.
*/
protected void sendResponse (ClientObject source, int invid,
String name, Object arg)
{
Object[] args = new Object[] { name, new Integer(invid), arg };
deliverResponse(source, args);
}
/**
* Delivers an invocation response properly configured with the
* supplied name and two arguments.
*/
protected void sendResponse (ClientObject source, int invid,
String name, Object arg1, Object arg2)
{
Object[] args = new Object[] {
name, new Integer(invid), arg1, arg2 };
deliverResponse(source, args);
}
/**
* Delivers an invocation response properly configured with the
* supplied name and three arguments.
*/
protected void sendResponse (ClientObject source, int invid,
String name, Object arg1, Object arg2,
Object arg3)
{
Object[] args = new Object[] {
name, new Integer(invid), arg1, arg2, arg3 };
deliverResponse(source, args);
}
/**
* Delivers an invocation response properly configured with the
* supplied name and varying number of arguments.
*/
protected void sendResponse (ClientObject source, int invid,
String name, Object[] args)
{
Object[] rargs = new Object[args.length+2];
rargs[0] = name;
rargs[1] = new Integer(invid);
System.arraycopy(args, 0, rargs, 2, args.length);
deliverResponse(source, rargs);
}
protected void deliverResponse (ClientObject source, Object[] args)
{
// make sure they didn't go away in the meanwhile
if (source.isActive()) {
// create the response event
MessageEvent mevt = new MessageEvent(
source.getOid(), InvocationObject.RESPONSE_NAME, args);
// and ship it off
PresentsServer.omgr.postEvent(mevt);
} else {
Log.warning("Dropping invrsp due to disappearing client " +
"[cloid=" + source.getOid() +
", args=" + StringUtil.toString(args) + "].");
}
}
}