001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.bytecode;
031:
032: import java.lang.ref.SoftReference;
033: import java.util.HashMap;
034: import java.util.logging.Logger;
035:
036: /**
037: * Manages an introspected java classes.
038: */
039: abstract public class JClassLoader {
040: protected static final Logger log = Logger
041: .getLogger(JClassLoader.class.getName());
042:
043: private static JClassLoaderWrapper _staticClassLoader;
044:
045: private static final HashMap<String, JClass> _staticClassMap = new HashMap<String, JClass>();
046:
047: private final HashMap<String, SoftReference<JClass>> _classMap = new HashMap<String, SoftReference<JClass>>();
048:
049: /**
050: * Returns the matching JClass.
051: */
052: public JClass forName(String name) {
053: SoftReference<JClass> jClassRef = _classMap.get(name);
054:
055: JClass jClass = jClassRef != null ? jClassRef.get() : null;
056:
057: if (jClass == null) {
058: jClass = _staticClassMap.get(name);
059:
060: if (jClass == null) {
061: if (name.startsWith("[")) {
062: JClass subClass = descriptorToClass(name, 1);
063: jClass = new JClassArray(subClass);
064: } else
065: jClass = loadClass(name);
066: }
067:
068: _classMap.put(name, new SoftReference<JClass>(jClass));
069: }
070:
071: return jClass;
072: }
073:
074: /**
075: * Closes the class loader.
076: */
077: public void close() {
078: _classMap.clear();
079: }
080:
081: /**
082: * Returns the matching JClass.
083: */
084: public static JClass systemForName(String name) {
085: return getSystemClassLoader().forName(name);
086: }
087:
088: /**
089: * Returns the wrapped system class loader.
090: */
091: static JClassLoader getSystemClassLoader() {
092: if (_staticClassLoader == null)
093: _staticClassLoader = JClassLoaderWrapper.create(ClassLoader
094: .getSystemClassLoader());
095:
096: return _staticClassLoader;
097: }
098:
099: /**
100: * Returns the matching JClass.
101: */
102: public static JClass localForName(String name) {
103: JClassLoaderWrapper jLoader = JClassLoaderWrapper.create();
104:
105: return jLoader.forName(name);
106: }
107:
108: /**
109: * Loads the class.
110: */
111: abstract protected JClass loadClass(String name);
112:
113: /**
114: * Returns the static class loader.
115: */
116: public static JClassLoader getStaticClassLoader() {
117: return getSystemClassLoader();
118: }
119:
120: public JClass descriptorToClass(String name, int i) {
121: switch (name.charAt(i)) {
122: case 'V':
123: return forName("void");
124: case 'Z':
125: return forName("boolean");
126: case 'C':
127: return forName("char");
128: case 'B':
129: return forName("byte");
130: case 'S':
131: return forName("short");
132: case 'I':
133: return forName("int");
134: case 'J':
135: return forName("long");
136: case 'F':
137: return forName("float");
138: case 'D':
139: return forName("double");
140: case '[':
141: return forName(name.substring(i));
142:
143: case 'L': {
144: int tail = name.indexOf(';', i);
145:
146: if (tail < 0)
147: throw new IllegalStateException(name);
148:
149: String className = name.substring(i + 1, tail).replace('/',
150: '.');
151:
152: return forName(className);
153: }
154:
155: default:
156: throw new UnsupportedOperationException(name.substring(i));
157: }
158: }
159:
160: public String toString() {
161: return "JClassLoader[]";
162: }
163:
164: static {
165: _staticClassMap.put("void", JClass.VOID);
166: _staticClassMap.put("boolean", JClass.BOOLEAN);
167: _staticClassMap.put("byte", JClass.BYTE);
168: _staticClassMap.put("short", JClass.SHORT);
169: _staticClassMap.put("int", JClass.INT);
170: _staticClassMap.put("long", JClass.LONG);
171: _staticClassMap.put("float", JClass.FLOAT);
172: _staticClassMap.put("double", JClass.DOUBLE);
173: _staticClassMap.put("char", JClass.CHAR);
174: _staticClassMap.put("java.lang.String", JClass.STRING);
175: _staticClassMap.put("java.lang.Object", JClass.OBJECT);
176: }
177: }
|