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