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., whether a class is a sub-class of another. 028 * Delegates actual class loading to SyntheticRepository with current class path by default. 029 * 030 * @see org.apache.bcel.util.Repository 031 * @see SyntheticRepository 032 * 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 * @return old entry in repository 042 */ 043 public static JavaClass addClass(final JavaClass clazz) { 044 final JavaClass old = repository.findClass(clazz.getClassName()); 045 repository.storeClass(clazz); 046 return old; 047 } 048 049 /** 050 * Clears the repository. 051 */ 052 public static void clearCache() { 053 repository.clear(); 054 } 055 056 /** 057 * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend, 058 * and so on. (Some people call this a transitive hull). 059 * @throws ClassNotFoundException if any of the class's superclasses or superinterfaces can't be found 060 */ 061 public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException { 062 return clazz.getAllInterfaces(); 063 } 064 065 /** 066 * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces, 067 * and so on 068 * @throws ClassNotFoundException if the named class can't be found, or if any of its superclasses or superinterfaces 069 * can't be found 070 */ 071 public static JavaClass[] getInterfaces(final String className) throws ClassNotFoundException { 072 return getInterfaces(lookupClass(className)); 073 } 074 075 /** 076 * @return currently used repository instance 077 */ 078 public static org.apache.bcel.util.Repository getRepository() { 079 return repository; 080 } 081 082 /** 083 * @return list of super classes of clazz in ascending order, i.e., Object is always the last element 084 * @throws ClassNotFoundException if any of the superclasses can't be found 085 */ 086 public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException { 087 return clazz.getSuperClasses(); 088 } 089 090 /** 091 * @return list of super classes of clazz in ascending order, i.e., Object is always the last element. 092 * @throws ClassNotFoundException if the named class or any of its superclasses can't be found 093 */ 094 public static JavaClass[] getSuperClasses(final String className) throws ClassNotFoundException { 095 return getSuperClasses(lookupClass(className)); 096 } 097 098 /** 099 * @return true, if clazz is an implementation of interface inter 100 * @throws ClassNotFoundException if any superclasses or superinterfaces of clazz can't be found 101 */ 102 public static boolean implementationOf(final JavaClass clazz, final JavaClass inter) throws ClassNotFoundException { 103 return clazz.implementationOf(inter); 104 } 105 106 /** 107 * @return true, if clazz is an implementation of interface inter 108 * @throws ClassNotFoundException if inter or any superclasses or superinterfaces of clazz can't be found 109 */ 110 public static boolean implementationOf(final JavaClass clazz, final String inter) throws ClassNotFoundException { 111 return implementationOf(clazz, lookupClass(inter)); 112 } 113 114 /** 115 * @return true, if clazz is an implementation of interface inter 116 * @throws ClassNotFoundException if clazz or any superclasses or superinterfaces of clazz can't be found 117 */ 118 public static boolean implementationOf(final String clazz, final JavaClass inter) throws ClassNotFoundException { 119 return implementationOf(lookupClass(clazz), inter); 120 } 121 122 /** 123 * @return true, if clazz is an implementation of interface inter 124 * @throws ClassNotFoundException if clazz, inter, or any superclasses or superinterfaces of clazz can't be found 125 */ 126 public static boolean implementationOf(final String clazz, final String inter) throws ClassNotFoundException { 127 return implementationOf(lookupClass(clazz), lookupClass(inter)); 128 } 129 130 /** 131 * Equivalent to runtime "instanceof" operator. 132 * 133 * @return true, if clazz is an instance of super_class 134 * @throws ClassNotFoundException if any superclasses or superinterfaces of clazz can't be found 135 */ 136 public static boolean instanceOf(final JavaClass clazz, final JavaClass super_class) throws ClassNotFoundException { 137 return clazz.instanceOf(super_class); 138 } 139 140 /** 141 * @return true, if clazz is an instance of super_class 142 * @throws ClassNotFoundException if super_class can't be found 143 */ 144 public static boolean instanceOf(final JavaClass clazz, final String super_class) throws ClassNotFoundException { 145 return instanceOf(clazz, lookupClass(super_class)); 146 } 147 148 /** 149 * @return true, if clazz is an instance of super_class 150 * @throws ClassNotFoundException if clazz can't be found 151 */ 152 public static boolean instanceOf(final String clazz, final JavaClass super_class) throws ClassNotFoundException { 153 return instanceOf(lookupClass(clazz), super_class); 154 } 155 156 /** 157 * @return true, if clazz is an instance of super_class 158 * @throws ClassNotFoundException if either clazz or super_class can't be found 159 */ 160 public static boolean instanceOf(final String clazz, final String super_class) throws ClassNotFoundException { 161 return instanceOf(lookupClass(clazz), lookupClass(super_class)); 162 } 163 164 /** 165 * Tries to find class source using the internal repository instance. 166 * 167 * @see Class 168 * @return JavaClass object for given runtime class 169 * @throws ClassNotFoundException if the class could not be found or parsed correctly 170 */ 171 public static JavaClass lookupClass(final Class<?> clazz) throws ClassNotFoundException { 172 return repository.loadClass(clazz); 173 } 174 175 /** 176 * Lookups class somewhere found on your CLASSPATH, or whereever the repository instance looks for it. 177 * 178 * @return class object for given fully qualified class name 179 * @throws ClassNotFoundException if the class could not be found or parsed correctly 180 */ 181 public static JavaClass lookupClass(final String className) throws ClassNotFoundException { 182 return repository.loadClass(className); 183 } 184 185 /** 186 * @return class file object for given Java class by looking on the system class path; returns null if the class file 187 * can't be found 188 */ 189 public static ClassPath.ClassFile lookupClassFile(final String className) { 190 try (final ClassPath path = repository.getClassPath()) { 191 if (path == null) { 192 return null; 193 } 194 return path.getClassFile(className); 195 } catch (final IOException e) { 196 return null; 197 } 198 } 199 200 /** 201 * Removes given class from repository. 202 */ 203 public static void removeClass(final JavaClass clazz) { 204 repository.removeClass(clazz); 205 } 206 207 /** 208 * Removes class with given (fully qualified) name from repository. 209 */ 210 public static void removeClass(final String clazz) { 211 repository.removeClass(repository.findClass(clazz)); 212 } 213 214 /** 215 * Sets repository instance to be used for class loading 216 */ 217 public static void setRepository(final org.apache.bcel.util.Repository rep) { 218 repository = rep; 219 } 220}