1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.bcel; 18 19 import java.io.IOException; 20 21 import org.apache.bcel.classfile.JavaClass; 22 import org.apache.bcel.util.ClassPath; 23 import org.apache.bcel.util.SyntheticRepository; 24 25 /** 26 * The repository maintains informations about class interdependencies, e.g., whether a class is a sub-class of another. 27 * Delegates actual class loading to SyntheticRepository with current class path by default. 28 * 29 * @see org.apache.bcel.util.Repository 30 * @see SyntheticRepository 31 */ 32 public abstract class Repository { 33 34 private static org.apache.bcel.util.Repository repository = SyntheticRepository.getInstance(); 35 36 /** 37 * Adds clazz to repository if there isn't an equally named class already in there. 38 * 39 * @return old entry in repository 40 */ 41 public static JavaClass addClass(final JavaClass clazz) { 42 final JavaClass old = repository.findClass(clazz.getClassName()); 43 repository.storeClass(clazz); 44 return old; 45 } 46 47 /** 48 * Clears the repository. 49 */ 50 public static void clearCache() { 51 repository.clear(); 52 } 53 54 /** 55 * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend, 56 * and so on. (Some people call this a transitive hull). 57 * @throws ClassNotFoundException if any of the class's superclasses or superinterfaces can't be found 58 */ 59 public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException { 60 return clazz.getAllInterfaces(); 61 } 62 63 /** 64 * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces, 65 * and so on 66 * @throws ClassNotFoundException if the named class can't be found, or if any of its superclasses or superinterfaces 67 * can't be found 68 */ 69 public static JavaClass[] getInterfaces(final String className) throws ClassNotFoundException { 70 return getInterfaces(lookupClass(className)); 71 } 72 73 /** 74 * @return currently used repository instance 75 */ 76 public static org.apache.bcel.util.Repository getRepository() { 77 return repository; 78 } 79 80 /** 81 * @return list of super classes of clazz in ascending order, i.e., Object is always the last element 82 * @throws ClassNotFoundException if any of the superclasses can't be found 83 */ 84 public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException { 85 return clazz.getSuperClasses(); 86 } 87 88 /** 89 * @return list of super classes of clazz in ascending order, i.e., Object is always the last element. 90 * @throws ClassNotFoundException if the named class or any of its superclasses can't be found 91 */ 92 public static JavaClass[] getSuperClasses(final String className) throws ClassNotFoundException { 93 return getSuperClasses(lookupClass(className)); 94 } 95 96 /** 97 * @return true, if clazz is an implementation of interface inter 98 * @throws ClassNotFoundException if any superclasses or superinterfaces of clazz can't be found 99 */ 100 public static boolean implementationOf(final JavaClass clazz, final JavaClass inter) throws ClassNotFoundException { 101 return clazz.implementationOf(inter); 102 } 103 104 /** 105 * @return true, if clazz is an implementation of interface inter 106 * @throws ClassNotFoundException if inter or any superclasses or superinterfaces of clazz can't be found 107 */ 108 public static boolean implementationOf(final JavaClass clazz, final String inter) throws ClassNotFoundException { 109 return implementationOf(clazz, lookupClass(inter)); 110 } 111 112 /** 113 * @return true, if clazz is an implementation of interface inter 114 * @throws ClassNotFoundException if clazz or any superclasses or superinterfaces of clazz can't be found 115 */ 116 public static boolean implementationOf(final String clazz, final JavaClass inter) throws ClassNotFoundException { 117 return implementationOf(lookupClass(clazz), inter); 118 } 119 120 /** 121 * @return true, if clazz is an implementation of interface inter 122 * @throws ClassNotFoundException if clazz, inter, or any superclasses or superinterfaces of clazz can't be found 123 */ 124 public static boolean implementationOf(final String clazz, final String inter) throws ClassNotFoundException { 125 return implementationOf(lookupClass(clazz), lookupClass(inter)); 126 } 127 128 /** 129 * Equivalent to runtime "instanceof" operator. 130 * 131 * @return true, if clazz is an instance of superclass 132 * @throws ClassNotFoundException if any superclasses or superinterfaces of clazz can't be found 133 */ 134 public static boolean instanceOf(final JavaClass clazz, final JavaClass superclass) throws ClassNotFoundException { 135 return clazz.instanceOf(superclass); 136 } 137 138 /** 139 * @return true, if clazz is an instance of superclass 140 * @throws ClassNotFoundException if superclass can't be found 141 */ 142 public static boolean instanceOf(final JavaClass clazz, final String superclass) throws ClassNotFoundException { 143 return instanceOf(clazz, lookupClass(superclass)); 144 } 145 146 /** 147 * @return true, if clazz is an instance of superclass 148 * @throws ClassNotFoundException if clazz can't be found 149 */ 150 public static boolean instanceOf(final String clazz, final JavaClass superclass) throws ClassNotFoundException { 151 return instanceOf(lookupClass(clazz), superclass); 152 } 153 154 /** 155 * @return true, if clazz is an instance of superclass 156 * @throws ClassNotFoundException if either clazz or superclass can't be found 157 */ 158 public static boolean instanceOf(final String clazz, final String superclass) throws ClassNotFoundException { 159 return instanceOf(lookupClass(clazz), lookupClass(superclass)); 160 } 161 162 /** 163 * Tries to find class source using the internal repository instance. 164 * 165 * @see Class 166 * @return JavaClass object for given runtime class 167 * @throws ClassNotFoundException if the class could not be found or parsed correctly 168 */ 169 public static JavaClass lookupClass(final Class<?> clazz) throws ClassNotFoundException { 170 return repository.loadClass(clazz); 171 } 172 173 /** 174 * Lookups class somewhere found on your CLASSPATH, or whereever the repository instance looks for it. 175 * 176 * @return class object for given fully qualified class name 177 * @throws ClassNotFoundException if the class could not be found or parsed correctly 178 */ 179 public static JavaClass lookupClass(final String className) throws ClassNotFoundException { 180 return repository.loadClass(className); 181 } 182 183 /** 184 * @return class file object for given Java class by looking on the system class path; returns null if the class file 185 * can't be found 186 */ 187 public static ClassPath.ClassFile lookupClassFile(final String className) { 188 try (ClassPath path = repository.getClassPath()) { 189 return path == null ? null : path.getClassFile(className); 190 } catch (final IOException e) { 191 return null; 192 } 193 } 194 195 /** 196 * Removes given class from repository. 197 */ 198 public static void removeClass(final JavaClass clazz) { 199 repository.removeClass(clazz); 200 } 201 202 /** 203 * Removes class with given (fully qualified) name from repository. 204 */ 205 public static void removeClass(final String clazz) { 206 repository.removeClass(repository.findClass(clazz)); 207 } 208 209 /** 210 * Sets repository instance to be used for class loading 211 */ 212 public static void setRepository(final org.apache.bcel.util.Repository rep) { 213 repository = rep; 214 } 215 }