View Javadoc
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, i.e., 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, i.e., 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 }