source: trunk/abcl/src/org/armedbear/lisp/JavaClass.java @ 12557

Last change on this file since 12557 was 12431, checked in by Mark Evenson, 15 years ago

Replace FastStringBuffer? with java.lang.StringBuilder?.

Phil Hudson suggested in Feburary 2009 that "[FastStringBuffer?] should
be removed with all references to it replaced with
java.lang.StringBuilder? once enough confidence in this change has been
gained." After almost a year of using FastStringBuffer? as a delagate
for StringBuilder?, that confidence has indeed been gained.

One subtlety for use of StringBuilder?: there is no

StringBuilder?(char)

constructor, so use

StringBuilder?(String.valueOf(c))

to construct a new StringBuilder? containing a single char. Otherwise
that char will get promoted to an int, and you will invoke

StringBuilder?(int capacity)

which will "swallow" the first character that you thought you were adding.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.0 KB
Line 
1/*
2 * BuiltInClass.java
3 *
4 * Copyright (C) 2003-2007 Peter Graves
5 * $Id: JavaClass.java 12431 2010-02-08 08:05:15Z mevenson $
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 static org.armedbear.lisp.Lisp.*;
25
26import java.util.HashMap;
27import java.util.HashSet;
28import java.util.LinkedList;
29import java.util.Map;
30import java.util.Queue;
31import java.util.Set;
32import java.util.Stack;
33
34public class JavaClass extends LispClass {
35
36  private Class<?> javaClass;
37  //There is no point for this Map to be weak since values keep a reference to the corresponding
38  //key (the Java class). This should not be a problem since Java classes are limited in number -
39  //if they grew indefinitely, the JVM itself would crash.
40  private static final Map<Class<?>, JavaClass> cache = new HashMap<Class<?>, JavaClass>();
41
42  private JavaClass(Class<?> javaClass) {
43      super(new Symbol(javaClass.getCanonicalName()));
44      this.javaClass = javaClass;
45      setDirectSuperclass(BuiltInClass.JAVA_OBJECT);
46  }
47
48  private void initCPL() {
49    LispObject cpl = Lisp.NIL;
50    cpl = cpl.push(BuiltInClass.CLASS_T);
51    cpl = cpl.push(BuiltInClass.JAVA_OBJECT);
52    Set<Class<?>> alreadySeen = new HashSet<Class<?>>();
53    Stack<JavaClass> stack = new Stack<JavaClass>();
54    Class<?> theClass = javaClass;
55    boolean stop = false;
56    while(!stop && theClass != null) {
57      stop = addClass(alreadySeen, stack, theClass);
58      for(Class<?> c : theClass.getInterfaces()) {
59        stop = addClass(alreadySeen, stack, c) && stop; //watch out for short-circuiting!
60      }
61      theClass = theClass.getSuperclass();
62    }
63    while(!stack.isEmpty()) {
64      cpl = cpl.push(stack.pop());
65    }
66    setCPL(cpl);
67  }
68
69  private static boolean addClass(Set<Class<?>> alreadySeen, Stack<JavaClass> stack, Class<?> theClass) {
70    if(!alreadySeen.contains(theClass)) {
71      alreadySeen.add(theClass);
72      stack.push(findJavaClass(theClass));
73      return false;
74    }
75    return true;
76  }
77
78  public LispObject typeOf() {
79    return Symbol.JAVA_CLASS;
80  }
81
82  public LispObject classOf() {
83    return StandardClass.JAVA_CLASS;
84  }
85
86  public LispObject typep(LispObject type) {
87    if (type == Symbol.JAVA_CLASS)
88      return T;
89    if (type == StandardClass.JAVA_CLASS)
90      return T;
91    return super.typep(type);
92  }
93
94  public LispObject getDescription() {
95    return new SimpleString(writeToString());
96  }
97
98  public String writeToString() {
99    StringBuilder sb = new StringBuilder("#<JAVA-CLASS ");
100    sb.append(javaClass.getCanonicalName());
101    sb.append('>');
102    return sb.toString();
103  }
104
105  public static JavaClass findJavaClass(Class<?> javaClass) {
106    synchronized (cache) {
107      JavaClass c = cache.get(javaClass);
108      if (c == null) {
109        c = new JavaClass(javaClass);
110        cache.put(javaClass, c);
111        c.initCPL();
112      }
113      return c;
114    }
115  }
116
117  public Class<?> getJavaClass() {
118    return javaClass;
119  }
120
121  public boolean subclassp(LispObject obj) {
122    if(obj == BuiltInClass.CLASS_T) {
123      return true;
124    }
125    if(obj == BuiltInClass.JAVA_OBJECT) {
126      return true;
127    }
128    if(obj instanceof JavaClass) {
129      return ((JavaClass) obj).getJavaClass().isAssignableFrom(javaClass);
130    }
131    return false;
132  }
133
134  private static final Primitive _FIND_JAVA_CLASS = new Primitive(
135      "%find-java-class", PACKAGE_JAVA, false, "string") {
136    public LispObject execute(LispObject arg) {
137        try {
138      return findJavaClass(Class.forName((String) arg.getStringValue()));
139        } catch (ClassNotFoundException e) {
140      return error(new LispError("Cannot find Java class " + arg.getStringValue()));
141        }
142    }
143
144  };
145
146}
Note: See TracBrowser for help on using the repository browser.