1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 package com.sun.org.apache.bcel.internal;
  21 
  22 
  23 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
  24 import com.sun.org.apache.bcel.internal.util.SyntheticRepository;
  25 
  26 /**
  27  * The repository maintains informations about class interdependencies, e.g.,
  28  * whether a class is a sub-class of another. Delegates actual class loading to
  29  * SyntheticRepository with current class path by default.
  30  *
  31  * @see com.sun.org.apache.bcel.internal.util.Repository
  32  * @see SyntheticRepository
  33  *
  34  * @version $Id: Repository.java 1749603 2016-06-21 20:50:19Z ggregory $
  35  */
  36 public abstract class Repository {
  37 
  38     private static com.sun.org.apache.bcel.internal.util.Repository repository
  39             = SyntheticRepository.getInstance();
  40 
  41     /**
  42      * @return currently used repository instance
  43      */
  44     public static com.sun.org.apache.bcel.internal.util.Repository getRepository() {
  45         return repository;
  46     }
  47 
  48     /**
  49      * Set repository instance to be used for class loading
  50      */
  51     public static void setRepository(final com.sun.org.apache.bcel.internal.util.Repository rep) {
  52         repository = rep;
  53     }
  54 
  55     /**
  56      * Lookup class somewhere found on your CLASSPATH, or whereever the
  57      * repository instance looks for it.
  58      *
  59      * @return class object for given fully qualified class name
  60      * @throws ClassNotFoundException if the class could not be found or parsed
  61      * correctly
  62      */
  63     public static JavaClass lookupClass(final String class_name)
  64             throws ClassNotFoundException {
  65         return repository.loadClass(class_name);
  66     }
  67 
  68     /**
  69      * Try to find class source using the internal repository instance.
  70      *
  71      * @see Class
  72      * @return JavaClass object for given runtime class
  73      * @throws ClassNotFoundException if the class could not be found or parsed
  74      * correctly
  75      */
  76     public static JavaClass lookupClass(final Class<?> clazz)
  77             throws ClassNotFoundException {
  78         return repository.loadClass(clazz);
  79     }
  80 
  81     /**
  82      * Clear the repository.
  83      */
  84     public static void clearCache() {
  85         repository.clear();
  86     }
  87 
  88     /**
  89      * Add clazz to repository if there isn't an equally named class already in
  90      * there.
  91      *
  92      * @return old entry in repository
  93      */
  94     public static JavaClass addClass(final JavaClass clazz) {
  95         final JavaClass old = repository.findClass(clazz.getClassName());
  96         repository.storeClass(clazz);
  97         return old;
  98     }
  99 
 100     /**
 101      * Remove class with given (fully qualified) name from repository.
 102      */
 103     public static void removeClass(final String clazz) {
 104         repository.removeClass(repository.findClass(clazz));
 105     }
 106 
 107     /**
 108      * Remove given class from repository.
 109      */
 110     public static void removeClass(final JavaClass clazz) {
 111         repository.removeClass(clazz);
 112     }
 113 
 114     /**
 115      * @return list of super classes of clazz in ascending order, i.e., Object
 116      * is always the last element
 117      * @throws ClassNotFoundException if any of the superclasses can't be found
 118      */
 119     public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException {
 120         return clazz.getSuperClasses();
 121     }
 122 
 123     /**
 124      * @return list of super classes of clazz in ascending order, i.e., Object
 125      * is always the last element.
 126      * @throws ClassNotFoundException if the named class or any of its
 127      * superclasses can't be found
 128      */
 129     public static JavaClass[] getSuperClasses(final String class_name) throws ClassNotFoundException {
 130         final JavaClass jc = lookupClass(class_name);
 131         return getSuperClasses(jc);
 132     }
 133 
 134     /**
 135      * @return all interfaces implemented by class and its super classes and the
 136      * interfaces that those interfaces extend, and so on. (Some people call
 137      * this a transitive hull).
 138      * @throws ClassNotFoundException if any of the class's superclasses or
 139      * superinterfaces can't be found
 140      */
 141     public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException {
 142         return clazz.getAllInterfaces();
 143     }
 144 
 145     /**
 146      * @return all interfaces implemented by class and its super classes and the
 147      * interfaces that extend those interfaces, and so on
 148      * @throws ClassNotFoundException if the named class can't be found, or if
 149      * any of its superclasses or superinterfaces can't be found
 150      */
 151     public static JavaClass[] getInterfaces(final String class_name) throws ClassNotFoundException {
 152         return getInterfaces(lookupClass(class_name));
 153     }
 154 
 155     /**
 156      * Equivalent to runtime "instanceof" operator.
 157      *
 158      * @return true, if clazz is an instance of super_class
 159      * @throws ClassNotFoundException if any superclasses or superinterfaces of
 160      * clazz can't be found
 161      */
 162     public static boolean instanceOf(final JavaClass clazz, final JavaClass super_class)
 163             throws ClassNotFoundException {
 164         return clazz.instanceOf(super_class);
 165     }
 166 
 167     /**
 168      * @return true, if clazz is an instance of super_class
 169      * @throws ClassNotFoundException if either clazz or super_class can't be
 170      * found
 171      */
 172     public static boolean instanceOf(final String clazz, final String super_class)
 173             throws ClassNotFoundException {
 174         return instanceOf(lookupClass(clazz), lookupClass(super_class));
 175     }
 176 
 177     /**
 178      * @return true, if clazz is an instance of super_class
 179      * @throws ClassNotFoundException if super_class can't be found
 180      */
 181     public static boolean instanceOf(final JavaClass clazz, final String super_class)
 182             throws ClassNotFoundException {
 183         return instanceOf(clazz, lookupClass(super_class));
 184     }
 185 
 186     /**
 187      * @return true, if clazz is an instance of super_class
 188      * @throws ClassNotFoundException if clazz can't be found
 189      */
 190     public static boolean instanceOf(final String clazz, final JavaClass super_class)
 191             throws ClassNotFoundException {
 192         return instanceOf(lookupClass(clazz), super_class);
 193     }
 194 
 195     /**
 196      * @return true, if clazz is an implementation of interface inter
 197      * @throws ClassNotFoundException if any superclasses or superinterfaces of
 198      * clazz can't be found
 199      */
 200     public static boolean implementationOf(final JavaClass clazz, final JavaClass inter)
 201             throws ClassNotFoundException {
 202         return clazz.implementationOf(inter);
 203     }
 204 
 205     /**
 206      * @return true, if clazz is an implementation of interface inter
 207      * @throws ClassNotFoundException if clazz, inter, or any superclasses or
 208      * superinterfaces of clazz can't be found
 209      */
 210     public static boolean implementationOf(final String clazz, final String inter)
 211             throws ClassNotFoundException {
 212         return implementationOf(lookupClass(clazz), lookupClass(inter));
 213     }
 214 
 215     /**
 216      * @return true, if clazz is an implementation of interface inter
 217      * @throws ClassNotFoundException if inter or any superclasses or
 218      * superinterfaces of clazz can't be found
 219      */
 220     public static boolean implementationOf(final JavaClass clazz, final String inter)
 221             throws ClassNotFoundException {
 222         return implementationOf(clazz, lookupClass(inter));
 223     }
 224 
 225     /**
 226      * @return true, if clazz is an implementation of interface inter
 227      * @throws ClassNotFoundException if clazz or any superclasses or
 228      * superinterfaces of clazz can't be found
 229      */
 230     public static boolean implementationOf(final String clazz, final JavaClass inter)
 231             throws ClassNotFoundException {
 232         return implementationOf(lookupClass(clazz), inter);
 233     }
 234 }