Nikita A. Visnevski wrote:
well, I just started playing with the BCEL package. I was totally
confused before. Stuff seems to work really well. I really enjoy the
package. This is exactly what I need. Thank you very much once again.
Well, I found your project interesting here's basically what you need.
Just call createBean and pass it a list of the bean properties and an
instance of BeanAdapter that knows how to store and retrieve bean data.
It's not perfect, but it's a start. Someone with more knowledge of the
JavaBeans specification could probably do a better job of getting all
the border cases right.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.Type;
public class DynamicBeanFactory implements Constants
{
private static final class BeanInvocationHandler
implements InvocationHandler
{
private final BeanAdapter adapter;
private BeanInvocationHandler(BeanAdapter adapter)
{
this.adapter = adapter;
}
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable
{
String methodName = method.getName();
if (methodName.startsWith("set"))
{
String propName =
Character.toLowerCase(methodName.charAt(3))
+ methodName.substring(4);
adapter.setProperty(propName, args[0]);
return null;
}
else if (methodName.startsWith("get"))
{
String propName =
Character.toLowerCase(methodName.charAt(3))
+ methodName.substring(4);
return adapter.getProperty(propName);
}
else if (methodName.startsWith("is"))
{
String propName =
Character.toLowerCase(methodName.charAt(2))
+ methodName.substring(3);
return adapter.getProperty(propName);
}
throw new RuntimeException(method.toString());
}
}
public static interface BeanAdapter
{
public void setProperty(String name, Object value);
public Object getProperty(String name);
}
public static Object createBean(
String[] propNames,
Class[] propTypes,
BeanAdapter adapter)
{
final String CLASS_NAME = "net.twu.cdsmith.BeanInterface";
ClassGen cg = new ClassGen(
CLASS_NAME, "java.lang.Object", null,
ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT,
new String[] { });
ConstantPoolGen cp = cg.getConstantPool();
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int i = 0; i < propNames.length; i++)
{
String methodName;
if (propTypes[i] == boolean.class)
{
methodName = "is"
+ Character.toUpperCase(propNames[i].charAt(0))
+ propNames[i].substring(1);
}
else
{
methodName = "get"
+ Character.toUpperCase(propNames[i].charAt(0))
+ propNames[i].substring(1);
}
Type t = Type.getType(propTypes[i]);
InstructionList il = new InstructionList();
MethodGen method = new MethodGen(ACC_PUBLIC | ACC_ABSTRACT,
t, Type.NO_ARGS, new String[] { },
methodName, CLASS_NAME, il, cp);
method.setMaxStack();
method.setMaxLocals();
cg.addMethod(method.getMethod());
il.dispose();
}
for (int i = 0; i < propNames.length; i++)
{
String methodName = "set"
+ Character.toUpperCase(propNames[i].charAt(0))
+ propNames[i].substring(1);
Type t = Type.getType(propTypes[i]);
InstructionList il = new InstructionList();
MethodGen method = new MethodGen(ACC_PUBLIC | ACC_ABSTRACT,
Type.VOID, new Type[] { t }, new String[] { "arg" },
methodName, CLASS_NAME, il, cp);
method.setMaxStack();
method.setMaxLocals();
cg.addMethod(method.getMethod());
il.dispose();
}
try
{
cg.getJavaClass().dump(out);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
final byte[] classData = out.toByteArray();
ClassLoader loader = new ClassLoader() {
protected Class findClass(String name)
throws ClassNotFoundException
{
return defineClass(
name, classData, 0, classData.length);
}
};
try
{
Class ifcClass = loader.loadClass(CLASS_NAME);
return Proxy.newProxyInstance(
loader, new Class[] { ifcClass },
new BeanInvocationHandler(adapter));
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
}
--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation