001: /*
002: * @(#)beanclass.java 1.3 05/04/20
003: *
004: * Copyright (c) 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package org.pnuts.lib;
010:
011: import pnuts.lang.Context;
012: import pnuts.lang.PnutsFunction;
013: import pnuts.lang.PnutsException;
014: import pnuts.compiler.ClassFile;
015: import pnuts.compiler.ClassFileHandler;
016: import java.util.Map;
017: import java.util.ArrayList;
018: import java.util.List;
019: import java.util.Iterator;
020: import org.pnuts.lang.SubtypeGenerator;
021: import org.pnuts.lang.ClassFileLoader;
022:
023: public class beanclass extends PnutsFunction {
024:
025: private ClassFileHandler handler;
026:
027: public beanclass() {
028: this (null);
029: }
030:
031: public beanclass(ClassFileHandler handler) {
032: super ("beanclass");
033: this .handler = handler;
034: }
035:
036: public boolean defined(int nargs) {
037: return nargs == 3 || nargs == 4;
038: }
039:
040: protected Object exec(Object[] args, Context context) {
041: int nargs = args.length;
042: if (nargs != 3 && nargs != 4) {
043: undefined(args, context);
044: return null;
045: }
046: String className = (String) args[0];
047:
048: Object super types = args[1];
049: ArrayList list;
050:
051: list = new ArrayList();
052: Class super class = subclass.parseSupertypes(super types, list,
053: context);
054: boolean serializable = false;
055: for (Iterator it = list.iterator(); it.hasNext();) {
056: Class type = (Class) it.next();
057: if (type.isAssignableFrom(java.io.Serializable.class)) {
058: serializable = true;
059: }
060: }
061: if (!serializable) {
062: list.add(java.io.Serializable.class);
063: }
064: String[] super Interfaces = new String[list.size()];
065: for (int i = 0; i < super Interfaces.length; i++) {
066: Class type = (Class) list.get(i);
067: super Interfaces[i] = type.getName();
068: }
069: Map typeMap = (Map) args[2];
070: String[] constructorParams;
071: if (args.length == 4) {
072: Object arg3 = args[3];
073: if (arg3 instanceof String[]) {
074: constructorParams = (String[]) arg3;
075: } else if (arg3 instanceof Object[]) {
076: int len = ((Object[]) arg3).length;
077: constructorParams = new String[len];
078: System.arraycopy(arg3, 0, constructorParams, 0, len);
079: } else if (arg3 instanceof List) {
080: List lst = (List) arg3;
081: int len = lst.size();
082: constructorParams = new String[len];
083: for (int i = 0; i < len; i++) {
084: constructorParams[i] = (String) lst.get(i);
085: }
086: } else {
087: throw new IllegalArgumentException(String.valueOf(arg3));
088: }
089: } else {
090: constructorParams = null;
091: }
092: try {
093: if (handler == null) {
094: Class[] types = new Class[list.size() + 1];
095: types[0] = super class;
096: for (int i = 0; i < list.size(); i++) {
097: types[i + 1] = (Class) list.get(i);
098: }
099: ClassLoader ccl = Thread.currentThread()
100: .getContextClassLoader();
101: ClassLoader cl = SubtypeGenerator.mergeClassLoader(
102: types, ccl);
103: handler = new ClassFileLoader(cl);
104: ClassLoader newCl = (ClassLoader) handler;
105: context.setClassLoader(newCl);
106: Thread.currentThread().setContextClassLoader(newCl);
107: }
108: ClassFile cf = BeanClassGenerator.generateClassFile(
109: typeMap, className, super class.getName(),
110: super Interfaces, constructorParams);
111: return handler.handle(cf);
112: } catch (Exception e) {
113: throw new PnutsException(e, context);
114: }
115: }
116:
117: public String toString() {
118: return "function beanclass(className, superInterfaces, typeMap {, constructorParams })";
119: }
120: }
|