1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * https://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.bcel;
20
21 import java.io.IOException;
22
23 import org.apache.bcel.classfile.JavaClass;
24 import org.apache.bcel.util.ClassPath;
25 import org.apache.bcel.util.SyntheticRepository;
26
27 /**
28 * The repository maintains informations about class interdependencies, for example, whether a class is a sub-class of another.
29 * Delegates actual class loading to SyntheticRepository with current class path by default.
30 *
31 * @see org.apache.bcel.util.Repository
32 * @see SyntheticRepository
33 */
34 public abstract class Repository {
35
36 private static org.apache.bcel.util.Repository repository = SyntheticRepository.getInstance();
37
38 /**
39 * Adds clazz to repository if there isn't an equally named class already in there.
40 *
41 * @return old entry in repository.
42 */
43 public static JavaClass addClass(final JavaClass clazz) {
44 final JavaClass old = repository.findClass(clazz.getClassName());
45 repository.storeClass(clazz);
46 return old;
47 }
48
49 /**
50 * Clears the repository.
51 */
52 public static void clearCache() {
53 repository.clear();
54 }
55
56 /**
57 * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend,
58 * and so on. (Some people call this a transitive hull).
59 * @throws ClassNotFoundException if any of the class's superclasses or superinterfaces can't be found
60 */
61 public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException {
62 return clazz.getAllInterfaces();
63 }
64
65 /**
66 * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces,
67 * and so on
68 * @throws ClassNotFoundException if the named class can't be found, or if any of its superclasses or superinterfaces
69 * can't be found
70 */
71 public static JavaClass[] getInterfaces(final String className) throws ClassNotFoundException {
72 return getInterfaces(lookupClass(className));
73 }
74
75 /**
76 * @return currently used repository instance.
77 */
78 public static org.apache.bcel.util.Repository getRepository() {
79 return repository;
80 }
81
82 /**
83 * @return list of super classes of clazz in ascending order, that is, Object is always the last element.
84 * @throws ClassNotFoundException if any of the superclasses can't be found
85 */
86 public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException {
87 return clazz.getSuperClasses();
88 }
89
90 /**
91 * @return list of super classes of clazz in ascending order, that is, Object is always the last element.
92 * @throws ClassNotFoundException if the named class or any of its superclasses can't be found
93 */
94 public static JavaClass[] getSuperClasses(final String className) throws ClassNotFoundException {
95 return getSuperClasses(lookupClass(className));
96 }
97
98 /**
99 * @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 superclass.
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 superclass) throws ClassNotFoundException {
137 return clazz.instanceOf(superclass);
138 }
139
140 /**
141 * @return true, if clazz is an instance of superclass.
142 * @throws ClassNotFoundException if superclass can't be found
143 */
144 public static boolean instanceOf(final JavaClass clazz, final String superclass) throws ClassNotFoundException {
145 return instanceOf(clazz, lookupClass(superclass));
146 }
147
148 /**
149 * @return true, if clazz is an instance of superclass.
150 * @throws ClassNotFoundException if clazz can't be found
151 */
152 public static boolean instanceOf(final String clazz, final JavaClass superclass) throws ClassNotFoundException {
153 return instanceOf(lookupClass(clazz), superclass);
154 }
155
156 /**
157 * @return true, if clazz is an instance of superclass.
158 * @throws ClassNotFoundException if either clazz or superclass can't be found
159 */
160 public static boolean instanceOf(final String clazz, final String superclass) throws ClassNotFoundException {
161 return instanceOf(lookupClass(clazz), lookupClass(superclass));
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 (ClassPath path = repository.getClassPath()) {
191 return path == null ? null : path.getClassFile(className);
192 } catch (final IOException e) {
193 return null;
194 }
195 }
196
197 /**
198 * Removes given class from repository.
199 */
200 public static void removeClass(final JavaClass clazz) {
201 repository.removeClass(clazz);
202 }
203
204 /**
205 * Removes class with given (fully qualified) name from repository.
206 */
207 public static void removeClass(final String clazz) {
208 repository.removeClass(repository.findClass(clazz));
209 }
210
211 /**
212 * Sets repository instance to be used for class loading
213 */
214 public static void setRepository(final org.apache.bcel.util.Repository rep) {
215 repository = rep;
216 }
217 }