1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.bcel.internal.util; 23 24 25 import java.io.*; 26 27 import java.util.Map; 28 import java.util.HashMap; 29 30 import com.sun.org.apache.bcel.internal.classfile.*; 31 32 /** 33 * This repository is used in situations where a Class is created 34 * outside the realm of a ClassLoader. Classes are loaded from 35 * the file systems using the paths specified in the given 36 * class path. By default, this is the value returned by 37 * ClassPath.getClassPath(). 38 * <br> 39 * It is designed to be used as a singleton, however it 40 * can also be used with custom classpaths. 41 * 42 /** 43 * Abstract definition of a class repository. Instances may be used 44 * to load classes from different sources and may be used in the 45 * Repository.setRepository method. 46 * 47 * @see com.sun.org.apache.bcel.internal.Repository 48 * 49 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 50 * @author David Dixon-Peugh 51 */ 52 public class SyntheticRepository implements Repository { 53 private static final String DEFAULT_PATH = ClassPath.getClassPath(); 54 55 private static HashMap _instances = new HashMap(); // CLASSPATH X REPOSITORY 56 57 private ClassPath _path = null; 58 private HashMap _loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS 59 60 private SyntheticRepository(ClassPath path) { 61 _path = path; 62 } 63 64 public static SyntheticRepository getInstance() { 65 return getInstance(ClassPath.SYSTEM_CLASS_PATH); 66 } 67 68 public static SyntheticRepository getInstance(ClassPath classPath) { 69 SyntheticRepository rep = (SyntheticRepository)_instances.get(classPath); 70 71 if(rep == null) { 72 rep = new SyntheticRepository(classPath); 73 _instances.put(classPath, rep); 74 } 75 76 return rep; 77 } 78 79 /** 80 * Store a new JavaClass instance into this Repository. 81 */ 82 public void storeClass(JavaClass clazz) { 83 _loadedClasses.put(clazz.getClassName(), clazz); 84 clazz.setRepository(this); 85 } 86 87 /** 88 * Remove class from repository 89 */ 90 public void removeClass(JavaClass clazz) { 91 _loadedClasses.remove(clazz.getClassName()); 92 } 93 94 /** 95 * Find an already defined (cached) JavaClass object by name. 96 */ 97 public JavaClass findClass(String className) { 98 return (JavaClass)_loadedClasses.get(className); 99 } 100 101 /** 102 * Load a JavaClass object for the given class name using 103 * the CLASSPATH environment variable. 104 */ 105 public JavaClass loadClass(String className) 106 throws ClassNotFoundException 107 { 108 if(className == null || className.equals("")) { 109 throw new IllegalArgumentException("Invalid class name " + className); 110 } 111 112 className = className.replace('/', '.'); // Just in case, canonical form 113 114 try { 115 return loadClass(_path.getInputStream(className), className); 116 } catch(IOException e) { 117 throw new ClassNotFoundException("Exception while looking for class " + 118 className + ": " + e.toString()); 119 } 120 } 121 122 /** 123 * Try to find class source via getResourceAsStream(). 124 * @see Class 125 * @return JavaClass object for given runtime class 126 */ 127 public JavaClass loadClass(Class clazz) throws ClassNotFoundException { 128 String className = clazz.getName(); 129 String name = className; 130 int i = name.lastIndexOf('.'); 131 132 if(i > 0) { 133 name = name.substring(i + 1); 134 } 135 136 return loadClass(clazz.getResourceAsStream(name + ".class"), className); 137 } 138 139 private JavaClass loadClass(InputStream is, String className) 140 throws ClassNotFoundException 141 { 142 JavaClass clazz = findClass(className); 143 144 if(clazz != null) { 145 return clazz; 146 } 147 148 try { 149 if(is != null) { 150 ClassParser parser = new ClassParser(is, className); 151 clazz = parser.parse(); 152 153 storeClass(clazz); 154 155 return clazz; 156 } 157 } catch(IOException e) { 158 throw new ClassNotFoundException("Exception while looking for class " + 159 className + ": " + e.toString()); 160 } 161 162 throw new ClassNotFoundException("SyntheticRepository could not load " + 163 className); 164 } 165 166 /** Clear all entries from cache. 167 */ 168 public void clear() { 169 _loadedClasses.clear(); 170 } 171 }