// Copyright (c) 2002 Dustin Sallings <dustin@spy.net>
package net.spy.util;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
* Create static proxy implementations of interfaces.
*
* This class is similiar to {@link InterfaceImplementor}, except it's used
* to create static proxy interface implementations which may be extended
* to override specific functionality (otherwise, the proxy would be kind
* of worthless, wouldn't it?).
*/
public class ProxyInterfaceImplementor extends InterfaceImplementor {
/**
* Get an instance of ProxyInterfaceImplementor.
*
* @param c the interface to be implemented
*
* @exception NullPointerException if the passed in class is null
* @exception IllegalArgumentException if the passed in class is not
* an interface
*/
public ProxyInterfaceImplementor(Class<?> c) {
super(c);
}
/**
* Don't create the default constructors.
*/
@Override
protected boolean buildConstructors() {
return(false);
}
/**
* Create the instance variables and constructor for the proxy.
*/
@Override
protected String preConstructors() {
Class<?> i=getInterface();
String ret="\tprivate " + i.getName() + " proxyedObject=null;\n\n";
ret+="\t/**\n"
+ "\t * Get a " + getOutClassName()
+ " proxying the provided object.\n"
+ "\t */\n";
ret+="\tprotected " + getOutClassName() + "("
+ i.getName() + " p) {\n"
+ "\t\tsuper();\n"
+ "\t\tthis.proxyedObject=p;\n"
+ "\t}\n\n";
return(ret);
}
/**
* Before the generated methods, include methods for accessing and
* setting the proxied object.
*/
@Override
protected String preMethods() {
Class<?> i=getInterface();
String rv=null;
rv ="\t/**\n"
+ "\t * Get the proxied object.\n"
+ "\t */\n";
rv+="\tprotected " + i.getName() + " getProxiedObject() {\n"
+ "\t\treturn(proxyedObject);\n"
+ "\t}\n";
rv+="\t/**\n"
+ "\t * Set the proxied object.\n"
+ "\t */\n";
rv+="\tprotected void setProxiedObject(" + i.getName() + " o) {\n"
+ "\t\tthis.proxyedObject=o;\n"
+ "\t}\n";
return(rv);
}
/**
* Implement this method as a proxy wrapper around the contained
* object.
*
* @param method the method to implement
*/
@Override
protected String implement(Method method) {
String ret="\t/**\n"
+ "\t * ProxyInterfaceImplementor implementation of "
+ method.getName() + ".\n"
+ "\t * @see " + getInterface().getName() + "#"
+ getDocLink(method) + "\n"
+ "\t */\n";
ret+="\t" + getSignature(method) + " {\n";
// Get the parameters
Class<?>[] types=method.getParameterTypes();
ArrayList<String> l=new ArrayList<String>(types.length);
for(int i=0; i<types.length; i++) {
l.add("a" + i);
}
String params=SpyUtil.join(l, ", ");
// make the call via the proxy object
Class<?> rt=method.getReturnType();
if(rt == Void.TYPE) {
ret+="\t\tproxyedObject." + method.getName() + "("
+ params
+ ");\n";
} else {
ret+="\t\treturn(proxyedObject." + method.getName() + "("
+ params
+ "));\n";
}
ret+="\t}\n\n";
return(ret);
}
private static void usage() {
System.err.println("Usage: ProxyInterfaceImplementor"
+ " -interface className [-outputclass className]\n"
+ "\t[-outputdir outputDir] [-superclass className]");
}
/**
* Create a proxy class for the specified interface.
*/
public static void main(String args[]) throws Exception {
String superclassName=null;
String interfaceName=null;
String outclass=null;
String outdir=".";
// Parse the arguments
for(int i=0; i<args.length; i++) {
if(args[i].equals("-superclass")) {
superclassName=args[++i];
} else if(args[i].equals("-interface")) {
interfaceName=args[++i];
} else if(args[i].equals("-outputclass")) {
outclass=args[++i];
} else if(args[i].equals("-outputdir")) {
outdir=args[++i];
} else {
System.err.println("Unknown argument: " + args[i]);
usage();
throw new Exception("Unknown argument: " + args[i]);
}
}
// make sure an interface name was given
if(interfaceName == null) {
System.err.println("No superinterface given.");
usage();
throw new Exception("No superinterface given.");
}
ProxyInterfaceImplementor i=
new ProxyInterfaceImplementor(Class.forName(interfaceName));
// Set the superclass
if(superclassName!=null) {
System.out.println("Loading super class: " + superclassName);
i.setSuperClass(Class.forName(superclassName));
}
// Figure out where to put the file
if(outclass!=null) {
// Set the output class name
i.setOutputClass(outclass);
i.writeSourceToFile(outdir);
} else {
System.out.print(i.makeSource());
}
}
}