KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > bcel > util > SyntheticRepository


1 /*
2  * Copyright 2000-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.bcel.util;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.lang.ref.SoftReference JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Map JavaDoc;
24 import org.apache.bcel.classfile.ClassParser;
25 import org.apache.bcel.classfile.JavaClass;
26
27 /**
28  * This repository is used in situations where a Class is created
29  * outside the realm of a ClassLoader. Classes are loaded from
30  * the file systems using the paths specified in the given
31  * class path. By default, this is the value returned by
32  * ClassPath.getClassPath().
33  * <br>
34  * It is designed to be used as a singleton, however it
35  * can also be used with custom classpaths.
36  *
37  /**
38  * Abstract definition of a class repository. Instances may be used
39  * to load classes from different sources and may be used in the
40  * Repository.setRepository method.
41  *
42  * @see org.apache.bcel.Repository
43  *
44  * @version $Id: SyntheticRepository.java 386056 2006-03-15 11:31:56Z tcurdt $
45  * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
46  * @author David Dixon-Peugh
47  */

48 public class SyntheticRepository implements Repository {
49
50     private static final String JavaDoc DEFAULT_PATH = ClassPath.getClassPath();
51     private static Map JavaDoc _instances = new HashMap JavaDoc(); // CLASSPATH X REPOSITORY
52
private ClassPath _path = null;
53     private Map JavaDoc _loadedClasses = new HashMap JavaDoc(); // CLASSNAME X JAVACLASS
54

55
56     private SyntheticRepository(ClassPath path) {
57         _path = path;
58     }
59
60
61     public static SyntheticRepository getInstance() {
62         return getInstance(ClassPath.SYSTEM_CLASS_PATH);
63     }
64
65
66     public static SyntheticRepository getInstance( ClassPath classPath ) {
67         SyntheticRepository rep = (SyntheticRepository) _instances.get(classPath);
68         if (rep == null) {
69             rep = new SyntheticRepository(classPath);
70             _instances.put(classPath, rep);
71         }
72         return rep;
73     }
74
75
76     /**
77      * Store a new JavaClass instance into this Repository.
78      */

79     public void storeClass( JavaClass clazz ) {
80         _loadedClasses.put(clazz.getClassName(), new SoftReference JavaDoc(clazz));
81         clazz.setRepository(this);
82     }
83
84
85     /**
86      * Remove class from repository
87      */

88     public void removeClass( JavaClass clazz ) {
89         _loadedClasses.remove(clazz.getClassName());
90     }
91
92
93     /**
94      * Find an already defined (cached) JavaClass object by name.
95      */

96     public JavaClass findClass( String JavaDoc className ) {
97         SoftReference JavaDoc ref = (SoftReference JavaDoc) _loadedClasses.get(className);
98         if (ref == null) {
99             return null;
100         }
101         return (JavaClass) ref.get();
102     }
103
104
105     /**
106      * Find a JavaClass object by name.
107      * If it is already in this Repository, the Repository version
108      * is returned. Otherwise, the Repository's classpath is searched for
109      * the class (and it is added to the Repository if found).
110      *
111      * @param className the name of the class
112      * @return the JavaClass object
113      * @throws ClassNotFoundException if the class is not in the
114      * Repository, and could not be found on the classpath
115      */

116     public JavaClass loadClass( String JavaDoc className ) throws ClassNotFoundException JavaDoc {
117         if (className == null || className.equals("")) {
118             throw new IllegalArgumentException JavaDoc("Invalid class name " + className);
119         }
120         className = className.replace('/', '.'); // Just in case, canonical form
121
JavaClass clazz = findClass(className);
122         if (clazz != null) {
123             return clazz;
124         }
125         try {
126             return loadClass(_path.getInputStream(className), className);
127         } catch (IOException JavaDoc e) {
128             throw new ClassNotFoundException JavaDoc("Exception while looking for class " + className
129                     + ": " + e.toString());
130         }
131     }
132
133
134     /**
135      * Find the JavaClass object for a runtime Class object.
136      * If a class with the same name is already in this Repository,
137      * the Repository version is returned. Otherwise, getResourceAsStream()
138      * is called on the Class object to find the class's representation.
139      * If the representation is found, it is added to the Repository.
140      *
141      * @see Class
142      * @param clazz the runtime Class object
143      * @return JavaClass object for given runtime class
144      * @throws ClassNotFoundException if the class is not in the
145      * Repository, and its representation could not be found
146      */

147     public JavaClass loadClass( Class JavaDoc clazz ) throws ClassNotFoundException JavaDoc {
148         String JavaDoc className = clazz.getName();
149         JavaClass repositoryClass = findClass(className);
150         if (repositoryClass != null) {
151             return repositoryClass;
152         }
153         String JavaDoc name = className;
154         int i = name.lastIndexOf('.');
155         if (i > 0) {
156             name = name.substring(i + 1);
157         }
158         return loadClass(clazz.getResourceAsStream(name + ".class"), className);
159     }
160
161
162     private JavaClass loadClass( InputStream JavaDoc is, String JavaDoc className ) throws ClassNotFoundException JavaDoc {
163         try {
164             if (is != null) {
165                 ClassParser parser = new ClassParser(is, className);
166                 JavaClass clazz = parser.parse();
167                 storeClass(clazz);
168                 return clazz;
169             }
170         } catch (IOException JavaDoc e) {
171             throw new ClassNotFoundException JavaDoc("Exception while looking for class " + className
172                     + ": " + e.toString());
173         }
174         throw new ClassNotFoundException JavaDoc("SyntheticRepository could not load " + className);
175     }
176
177
178     /** ClassPath associated with the Repository.
179      */

180     public ClassPath getClassPath() {
181         return _path;
182     }
183
184
185     /** Clear all entries from cache.
186      */

187     public void clear() {
188         _loadedClasses.clear();
189     }
190 }
191
Popular Tags