Allow an InvocationListener interface to extend another InvocationListener
interface. The way this works is a little tricky, but it all works out. We have a service SceneService with SceneMoveListener declaration. You can make FooSceneService and have a method in that service take a FooMoveListener which extends SceneMoveListener. An instance of FooMoveMarshaller will only be created if you call the method on FooSceneService and that will result in an object on the server side that implements SceneMoveListener, but calls to the SceneMoveListener response methods will result in the FooSceneService response codes being marshalled and sent back to the caller. So you can pass the FooMoveListener around to code on the server that expects a SceneMoveListener and it will magically do the right thing when server code calls through the SceneMoveListener interface. You can even turn around and pass the FooMoveMarshaller to another invocation service method (on a peer perhaps) that takes SceneMoveListener and it will work because the SceneService call will generate a SceneMoveMarshaller on the remote server, which will use the SceneMoveMarshaller's codes to communicate the response back to the first peer, which will unmap those and call the methods on the SceneMoveListener interface which will remarshal them with the FooMoveListener's codes and send them back to the client, and bob is everyone's uncle. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5891 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -24,7 +24,7 @@ package com.threerings.presents.tools;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.StringWriter;
|
||||
@@ -74,26 +74,46 @@ public class GenServiceTask extends InvocationTask
|
||||
public ServiceListener (Class<?> service, Class<?> listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
Method[] methdecls = listener.getDeclaredMethods();
|
||||
for (Method m : methdecls) {
|
||||
// service interface methods must be public and abstract
|
||||
if (!Modifier.isPublic(m.getModifiers()) &&
|
||||
!Modifier.isAbstract(m.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
if (_verbose) {
|
||||
System.out.println("Adding " + m + ", imports are " +
|
||||
StringUtil.toString(imports));
|
||||
}
|
||||
methods.add(new ServiceMethod(m, imports));
|
||||
if (_verbose) {
|
||||
System.out.println("Added " + m + ", imports are " +
|
||||
StringUtil.toString(imports));
|
||||
|
||||
// compute the union of all InvocationListener extensions implemented by this interface
|
||||
Set<Class<?>> ifaces = Sets.newHashSet();
|
||||
addInterfaces(listener, ifaces);
|
||||
|
||||
// add method marshallers for all methods in all interfaces (the marshaller will not
|
||||
// extend the marshallers for its parent interfaces and will use its own codes)
|
||||
for (Class<?> iface : ifaces) {
|
||||
Method[] methdecls = iface.getDeclaredMethods();
|
||||
for (Method m : methdecls) {
|
||||
// service interface methods must be public and abstract
|
||||
if (!Modifier.isPublic(m.getModifiers()) &&
|
||||
!Modifier.isAbstract(m.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
if (_verbose) {
|
||||
System.out.println("Adding " + m + ", imports are " +
|
||||
StringUtil.toString(imports));
|
||||
}
|
||||
methods.add(new ServiceMethod(m, imports));
|
||||
if (_verbose) {
|
||||
System.out.println("Added " + m + ", imports are " +
|
||||
StringUtil.toString(imports));
|
||||
}
|
||||
}
|
||||
}
|
||||
methods.sort();
|
||||
}
|
||||
|
||||
protected void addInterfaces (Class<?> listener, Set<Class<?>> ifaces)
|
||||
{
|
||||
if (!_ilistener.isAssignableFrom(listener) || _ilistener.equals(listener)) {
|
||||
return;
|
||||
}
|
||||
ifaces.add(listener);
|
||||
for (Class<?> iface : listener.getInterfaces()) {
|
||||
addInterfaces(iface, ifaces);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether any of our methods have parameterized types.
|
||||
*/
|
||||
@@ -668,10 +688,10 @@ public class GenServiceTask extends InvocationTask
|
||||
protected File _asroot;
|
||||
|
||||
/** Services for which we should not generate provider interfaces. */
|
||||
protected HashSet<String> _providerless = Sets.newHashSet();
|
||||
protected Set<String> _providerless = Sets.newHashSet();
|
||||
|
||||
/** Services for which we should generate actionscript listener adapters. */
|
||||
protected HashSet<String> _aslistenerAdapters = Sets.newHashSet();
|
||||
protected Set<String> _aslistenerAdapters = Sets.newHashSet();
|
||||
|
||||
/** Specifies the path to the marshaller template. */
|
||||
protected static final String MARSHALLER_TMPL =
|
||||
|
||||
Reference in New Issue
Block a user