source: branches/0.17.x/abcl/src/org/armedbear/lisp/JavaClass.java

Last change on this file was 12255, checked in by ehuelsmann, 16 years ago

Rename ConditionThrowable? to ControlTransfer? and remove

try/catch blocks which don't have anything to do with
non-local transfer of control.

  • Property svn:eol-style set to native
File size: 4.0 KB
Line 
1/*
2 * BuiltInClass.java
3 *
4 * Copyright (C) 2003-2007 Peter Graves
5 * $Id: BuiltInClass.java 11297 2008-08-31 13:26:45Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22package org.armedbear.lisp;
23
24import java.util.HashMap;
25import java.util.HashSet;
26import java.util.LinkedList;
27import java.util.Map;
28import java.util.Queue;
29import java.util.Set;
30import java.util.Stack;
31
32public class JavaClass extends LispClass {
33
34  private Class<?> javaClass;
35  //There is no point for this Map to be weak since values keep a reference to the corresponding
36  //key (the Java class). This should not be a problem since Java classes are limited in number -
37  //if they grew indefinitely, the JVM itself would crash.
38  private static final Map<Class<?>, JavaClass> cache = new HashMap<Class<?>, JavaClass>();
39
40  private JavaClass(Class<?> javaClass) {
41    this.javaClass = javaClass;
42    setDirectSuperclass(BuiltInClass.JAVA_OBJECT);
43  }
44
45  private void initCPL() {
46    LispObject cpl = Lisp.NIL;
47    cpl = cpl.push(BuiltInClass.CLASS_T);
48    cpl = cpl.push(BuiltInClass.JAVA_OBJECT);
49    Set<Class<?>> alreadySeen = new HashSet<Class<?>>();
50    Stack<JavaClass> stack = new Stack<JavaClass>();
51    Class<?> theClass = javaClass;
52    boolean stop = false;
53    while(!stop && theClass != null) {
54      stop = addClass(alreadySeen, stack, theClass);
55      for(Class<?> c : theClass.getInterfaces()) {
56        stop = addClass(alreadySeen, stack, c) && stop; //watch out for short-circuiting!
57      }
58      theClass = theClass.getSuperclass();
59    }
60    while(!stack.isEmpty()) {
61      cpl = cpl.push(stack.pop());
62    }
63    setCPL(cpl);
64  }
65
66  private static boolean addClass(Set<Class<?>> alreadySeen, Stack<JavaClass> stack, Class<?> theClass) {
67    if(!alreadySeen.contains(theClass)) {
68      alreadySeen.add(theClass);
69      stack.push(findJavaClass(theClass));
70      return false;
71    }
72    return true;
73  }
74
75  public LispObject typeOf() {
76    return Symbol.JAVA_CLASS;
77  }
78
79  public LispObject classOf() {
80    return StandardClass.JAVA_CLASS;
81  }
82
83  public LispObject typep(LispObject type) {
84    if (type == Symbol.JAVA_CLASS)
85      return T;
86    if (type == StandardClass.JAVA_CLASS)
87      return T;
88    return super.typep(type);
89  }
90
91  public LispObject getDescription() {
92    return new SimpleString(writeToString());
93  }
94
95  public String writeToString() {
96    FastStringBuffer sb = new FastStringBuffer("#<JAVA-CLASS ");
97    sb.append(javaClass.getCanonicalName());
98    sb.append('>');
99    return sb.toString();
100  }
101
102  public static JavaClass findJavaClass(Class<?> javaClass) {
103    synchronized (cache) {
104      JavaClass c = cache.get(javaClass);
105      if (c == null) {
106        c = new JavaClass(javaClass);
107        cache.put(javaClass, c);
108        c.initCPL();
109      }
110      return c;
111    }
112  }
113
114  public Class<?> getJavaClass() {
115    return javaClass;
116  }
117
118  public boolean subclassp(LispObject obj) {
119    if(obj == BuiltInClass.CLASS_T) {
120      return true;
121    }
122    if(obj == BuiltInClass.JAVA_OBJECT) {
123      return true;
124    }
125    if(obj instanceof JavaClass) {
126      return ((JavaClass) obj).getJavaClass().isAssignableFrom(javaClass);
127    }
128    return false;
129  }
130
131  private static final Primitive _FIND_JAVA_CLASS = new Primitive(
132      "%find-java-class", PACKAGE_JAVA, false, "string") {
133    public LispObject execute(LispObject arg) {
134        try {
135      return findJavaClass(Class.forName((String) arg.getStringValue()));
136        } catch (ClassNotFoundException e) {
137      return error(new LispError("Cannot find Java class " + arg.getStringValue()));
138        }
139    }
140
141  };
142
143}
Note: See TracBrowser for help on using the repository browser.