[armedbear-cvs] r11381 - branches/scripting/j/src/org/armedbear/lisp

Alessio Stalla astalla at common-lisp.net
Thu Nov 6 19:27:23 UTC 2008


Author: astalla
Date: Thu Nov  6 19:27:23 2008
New Revision: 11381

Log:
Added missing JavaClass.java

Added:
   branches/scripting/j/src/org/armedbear/lisp/JavaClass.java

Added: branches/scripting/j/src/org/armedbear/lisp/JavaClass.java
==============================================================================
--- (empty file)
+++ branches/scripting/j/src/org/armedbear/lisp/JavaClass.java	Thu Nov  6 19:27:23 2008
@@ -0,0 +1,147 @@
+/*
+ * BuiltInClass.java
+ *
+ * Copyright (C) 2003-2007 Peter Graves
+ * $Id: BuiltInClass.java 11297 2008-08-31 13:26:45Z ehuelsmann $
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+package org.armedbear.lisp;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.Stack;
+
+public class JavaClass extends LispClass {
+
+	private Class<?> javaClass;
+	//There is no point for this Map to be weak since values keep a reference to the corresponding
+	//key (the Java class). This should not be a problem since Java classes are limited in number - 
+	//if they grew indefinitely, the JVM itself would crash.
+	private static final Map<Class<?>, JavaClass> cache = new HashMap<Class<?>, JavaClass>();
+
+	private JavaClass(Class<?> javaClass) {
+		this.javaClass = javaClass;
+		setDirectSuperclass(BuiltInClass.JAVA_OBJECT);
+	}
+
+	private void initCPL() {
+		LispObject cpl = Lisp.NIL;
+		try {
+			cpl = cpl.push(BuiltInClass.CLASS_T);
+			cpl = cpl.push(BuiltInClass.JAVA_OBJECT);
+			Set<Class<?>> alreadySeen = new HashSet<Class<?>>();
+			Stack<JavaClass> stack = new Stack<JavaClass>();
+			Class<?> theClass = javaClass;
+			boolean stop = false;
+			while(!stop && theClass != null) {
+				stop = addClass(alreadySeen, stack, theClass);
+				for(Class<?> c : theClass.getInterfaces()) {
+					stop = addClass(alreadySeen, stack, c) && stop; //watch out for short-circuiting!
+				}
+				theClass = theClass.getSuperclass();
+			}
+			while(!stack.isEmpty()) {
+				cpl = cpl.push(stack.pop());
+			}
+		} catch (ConditionThrowable e) {
+			throw new Error("Cannot push class in class precedence list", e);
+		}
+		setCPL(cpl);
+	}
+
+	private static boolean addClass(Set<Class<?>> alreadySeen, Stack<JavaClass> stack, Class<?> theClass) {
+		if(!alreadySeen.contains(theClass)) {
+			alreadySeen.add(theClass);
+			stack.push(findJavaClass(theClass));
+			return false;
+		}
+		return true;
+	}
+
+	public LispObject typeOf() {
+		return Symbol.JAVA_CLASS;
+	}
+
+	public LispObject classOf() {
+		return StandardClass.JAVA_CLASS;
+	}
+
+	public LispObject typep(LispObject type) throws ConditionThrowable {
+		if (type == Symbol.JAVA_CLASS)
+			return T;
+		if (type == StandardClass.JAVA_CLASS)
+			return T;
+		return super.typep(type);
+	}
+
+	public LispObject getDescription() throws ConditionThrowable {
+		return new SimpleString(writeToString());
+	}
+
+	public String writeToString() throws ConditionThrowable {
+		FastStringBuffer sb = new FastStringBuffer("#<JAVA-CLASS ");
+		sb.append(javaClass.getCanonicalName());
+		sb.append('>');
+		return sb.toString();
+	}
+
+	public static JavaClass findJavaClass(Class<?> javaClass) {
+		synchronized (cache) {
+			JavaClass c = cache.get(javaClass);
+			if (c == null) {
+				c = new JavaClass(javaClass);
+				cache.put(javaClass, c);
+				c.initCPL();
+			}
+			return c;
+		}
+	}
+
+	public Class<?> getJavaClass() {
+		return javaClass;
+	}
+
+	public boolean subclassp(LispObject obj) throws ConditionThrowable {
+		if(obj == BuiltInClass.CLASS_T) {
+			return true;
+		}
+		if(obj == BuiltInClass.JAVA_OBJECT) {
+			return true;
+		}
+		if(obj instanceof JavaClass) {
+			return ((JavaClass) obj).getJavaClass().isAssignableFrom(javaClass);
+		}
+		return false;
+	}
+
+	private static final Primitive _FIND_JAVA_CLASS = new Primitive(
+			"%find-java-class", PACKAGE_JAVA, false, "string") {
+		public LispObject execute(LispObject arg) throws ConditionThrowable {
+			try {
+				return findJavaClass(Class.forName((String) arg.getStringValue()));
+			} catch (ClassNotFoundException e) {
+				throw new ConditionThrowable("Cannot find Java class " + arg.getStringValue());
+			}
+		}
+
+	};
+
+}




More information about the armedbear-cvs mailing list