001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.bcel; 020 021import java.io.IOException; 022 023import org.apache.bcel.classfile.JavaClass; 024import org.apache.bcel.util.ClassPath; 025import org.apache.bcel.util.SyntheticRepository; 026 027/** 028 * The repository maintains informations about class interdependencies, for example, whether a class is a sub-class of another. 029 * Delegates actual class loading to SyntheticRepository with current class path by default. 030 * 031 * @see org.apache.bcel.util.Repository 032 * @see SyntheticRepository 033 */ 034public abstract class Repository { 035 036 private static org.apache.bcel.util.Repository repository = SyntheticRepository.getInstance(); 037 038 /** 039 * Adds clazz to repository if there isn't an equally named class already in there. 040 * 041 * @param clazz The class to add. 042 * @return old entry in repository. 043 */ 044 public static JavaClass addClass(final JavaClass clazz) { 045 final JavaClass old = repository.findClass(clazz.getClassName()); 046 repository.storeClass(clazz); 047 return old; 048 } 049 050 /** 051 * Clears the repository. 052 */ 053 public static void clearCache() { 054 repository.clear(); 055 } 056 057 /** 058 * Gets all interfaces implemented by the class. 059 * 060 * @param clazz The class. 061 * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend, 062 * and so on. (Some people call this a transitive hull). 063 * @throws ClassNotFoundException Thrown if any of the class's superclasses or superinterfaces can't be found. 064 */ 065 public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException { 066 return clazz.getAllInterfaces(); 067 } 068 069 /** 070 * Gets all interfaces implemented by the class. 071 * 072 * @param className The class name. 073 * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces, 074 * and so on. 075 * @throws ClassNotFoundException Thrown if the named class can't be found, or if any of its superclasses or superinterfaces 076 * can't be found. 077 */ 078 public static JavaClass[] getInterfaces(final String className) throws ClassNotFoundException { 079 return getInterfaces(lookupClass(className)); 080 } 081 082 /** 083 * Gets the currently used repository instance. 084 * 085 * @return currently used repository instance. 086 */ 087 public static org.apache.bcel.util.Repository getRepository() { 088 return repository; 089 } 090 091 /** 092 * Gets the list of super classes. 093 * 094 * @param clazz The class. 095 * @return list of super classes of clazz in ascending order, that is, Object is always the last element. 096 * @throws ClassNotFoundException Thrown if any of the superclasses can't be found. 097 */ 098 public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException { 099 return clazz.getSuperClasses(); 100 } 101 102 /** 103 * Gets the list of super classes. 104 * 105 * @param className The class name. 106 * @return list of super classes of clazz in ascending order, that is, Object is always the last element. 107 * @throws ClassNotFoundException Thrown if the named class or any of its superclasses can't be found. 108 */ 109 public static JavaClass[] getSuperClasses(final String className) throws ClassNotFoundException { 110 return getSuperClasses(lookupClass(className)); 111 } 112 113 /** 114 * Tests if clazz is an implementation of interface inter. 115 * 116 * @param clazz The class to test. 117 * @param inter The interface. 118 * @return true, if clazz is an implementation of interface inter. 119 * @throws ClassNotFoundException Thrown if any superclasses or superinterfaces of clazz can't be found. 120 */ 121 public static boolean implementationOf(final JavaClass clazz, final JavaClass inter) throws ClassNotFoundException { 122 return clazz.implementationOf(inter); 123 } 124 125 /** 126 * Tests if clazz is an implementation of interface inter. 127 * 128 * @param clazz The class to test. 129 * @param inter The interface name. 130 * @return true, if clazz is an implementation of interface inter. 131 * @throws ClassNotFoundException Thrown if inter or any superclasses or superinterfaces of clazz can't be found. 132 */ 133 public static boolean implementationOf(final JavaClass clazz, final String inter) throws ClassNotFoundException { 134 return implementationOf(clazz, lookupClass(inter)); 135 } 136 137 /** 138 * Tests if clazz is an implementation of interface inter. 139 * 140 * @param clazz The class name to test. 141 * @param inter The interface. 142 * @return true, if clazz is an implementation of interface inter. 143 * @throws ClassNotFoundException Thrown if clazz or any superclasses or superinterfaces of clazz can't be found. 144 */ 145 public static boolean implementationOf(final String clazz, final JavaClass inter) throws ClassNotFoundException { 146 return implementationOf(lookupClass(clazz), inter); 147 } 148 149 /** 150 * Tests if clazz is an implementation of interface inter. 151 * 152 * @param clazz The class name to test. 153 * @param inter The interface name. 154 * @return true, if clazz is an implementation of interface inter. 155 * @throws ClassNotFoundException Thrown if clazz, inter, or any superclasses or superinterfaces of clazz can't be found. 156 */ 157 public static boolean implementationOf(final String clazz, final String inter) throws ClassNotFoundException { 158 return implementationOf(lookupClass(clazz), lookupClass(inter)); 159 } 160 161 /** 162 * Equivalent to runtime "instanceof" operator. 163 * 164 * @param clazz The class to test. 165 * @param superclass The superclass. 166 * @return true, if clazz is an instance of superclass. 167 * @throws ClassNotFoundException Thrown if any superclasses or superinterfaces of clazz can't be found. 168 */ 169 public static boolean instanceOf(final JavaClass clazz, final JavaClass superclass) throws ClassNotFoundException { 170 return clazz.instanceOf(superclass); 171 } 172 173 /** 174 * Tests if clazz is an instance of superclass. 175 * 176 * @param clazz The class to test. 177 * @param superclass The superclass name. 178 * @return true, if clazz is an instance of superclass. 179 * @throws ClassNotFoundException Thrown if superclass can't be found. 180 */ 181 public static boolean instanceOf(final JavaClass clazz, final String superclass) throws ClassNotFoundException { 182 return instanceOf(clazz, lookupClass(superclass)); 183 } 184 185 /** 186 * Tests if clazz is an instance of superclass. 187 * 188 * @param clazz The class name to test. 189 * @param superclass The superclass. 190 * @return true, if clazz is an instance of superclass. 191 * @throws ClassNotFoundException Thrown if clazz can't be found. 192 */ 193 public static boolean instanceOf(final String clazz, final JavaClass superclass) throws ClassNotFoundException { 194 return instanceOf(lookupClass(clazz), superclass); 195 } 196 197 /** 198 * Tests if clazz is an instance of superclass. 199 * 200 * @param clazz The class name to test. 201 * @param superclass The superclass name. 202 * @return true, if clazz is an instance of superclass. 203 * @throws ClassNotFoundException Thrown if either clazz or superclass can't be found. 204 */ 205 public static boolean instanceOf(final String clazz, final String superclass) throws ClassNotFoundException { 206 return instanceOf(lookupClass(clazz), lookupClass(superclass)); 207 } 208 209 /** 210 * Tries to find class source using the internal repository instance. 211 * 212 * @param clazz The class. 213 * @see Class 214 * @return JavaClass object for given runtime class. 215 * @throws ClassNotFoundException Thrown if the class could not be found or parsed correctly. 216 */ 217 public static JavaClass lookupClass(final Class<?> clazz) throws ClassNotFoundException { 218 return repository.loadClass(clazz); 219 } 220 221 /** 222 * Lookups class somewhere found on your CLASSPATH, or wherever the repository instance looks for it. 223 * 224 * @param className The class name. 225 * @return class object for given fully qualified class name. 226 * @throws ClassNotFoundException Thrown if the class could not be found or parsed correctly. 227 */ 228 public static JavaClass lookupClass(final String className) throws ClassNotFoundException { 229 return repository.loadClass(className); 230 } 231 232 /** 233 * Looks up the class file. 234 * 235 * @param className The class name. 236 * @return class file object for given Java class by looking on the system class path; returns null if the class file 237 * can't be found. 238 */ 239 public static ClassPath.ClassFile lookupClassFile(final String className) { 240 try (ClassPath path = repository.getClassPath()) { 241 return path == null ? null : path.getClassFile(className); 242 } catch (final IOException e) { 243 return null; 244 } 245 } 246 247 /** 248 * Removes given class from repository. 249 * 250 * @param clazz The class to remove. 251 */ 252 public static void removeClass(final JavaClass clazz) { 253 repository.removeClass(clazz); 254 } 255 256 /** 257 * Removes class with given (fully qualified) name from repository. 258 * 259 * @param clazz The class name to remove. 260 */ 261 public static void removeClass(final String clazz) { 262 repository.removeClass(repository.findClass(clazz)); 263 } 264 265 /** 266 * Sets repository instance to be used for class loading. 267 * 268 * @param rep The repository instance. 269 */ 270 public static void setRepository(final org.apache.bcel.util.Repository rep) { 271 repository = rep; 272 } 273 274 /** 275 * Constructs a new Repository. 276 */ 277 public Repository() { 278 } 279}