    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 * @version $Id: Repository.java 1749603 2016-06-21 20:50:19Z ggregory $
    035 */
    036public abstract class Repository {
    037
    038    private static org.apache.bcel.util.Repository repository = SyntheticRepository.getInstance();
    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    /** Set repository instance to be used for class loading
    049     */
    050    public static void setRepository( final org.apache.bcel.util.Repository rep ) {
    051        repository = rep;
    052    }
    053
    054
    055    /** Lookup class somewhere found on your CLASSPATH, or whereever the
    056     * repository instance looks for it.
    057     *
    058     * @return class object for given fully qualified class name
    059     * @throws ClassNotFoundException if the class could not be found or
    060     * parsed correctly
    061     */
    062    public static JavaClass lookupClass( final String class_name ) throws ClassNotFoundException {
    063        return repository.loadClass(class_name);
    064    }
    065
    066
    067    /**
    068     * Try to find class source using the internal repository instance.
    069     * @see Class
    070     * @return JavaClass object for given runtime class
    071     * @throws ClassNotFoundException if the class could not be found or
    072     * parsed correctly
    073     */
    074    public static JavaClass lookupClass( final Class<?> clazz ) throws ClassNotFoundException {
    075        return repository.loadClass(clazz);
    076    }
    077
    078
    079    /**
    080     * @return class file object for given Java class by looking on the
    081     *  system class path; returns null if the class file can't be
    082     *  found
    083     */
    084    public static ClassPath.ClassFile lookupClassFile( final String class_name ) {
    085        try {
    086            final ClassPath path = repository.getClassPath();
    087            if (path == null) {
    088                return null;
    089            }
    090            return path.getClassFile(class_name);
    091        } catch (final IOException e) {
    092            return null;
    093        }
    094    }
    095
    096
    097    /** Clear the repository.
    098     */
    099    public static void clearCache() {
    100        repository.clear();
    101    }
    102
    103
    104    /**
    105     * Add clazz to repository if there isn't an equally named class already in there.
    106     *
    107     * @return old entry in repository
    108     */
    109    public static JavaClass addClass( final JavaClass clazz ) {
    110        final JavaClass old = repository.findClass(clazz.getClassName());
    111        repository.storeClass(clazz);
    112        return old;
    113    }
    114
    115
    116    /**
    117     * Remove class with given (fully qualified) name from repository.
    118     */
    119    public static void removeClass( final String clazz ) {
    120        repository.removeClass(repository.findClass(clazz));
    121    }
    122
    123
    124    /**
    125     * Remove given class from repository.
    126     */
    127    public static void removeClass( final JavaClass clazz ) {
    128        repository.removeClass(clazz);
    129    }
    130
    131
    132    /**
    133     * @return list of super classes of clazz in ascending order, i.e.,
    134     * Object is always the last element
    135     * @throws ClassNotFoundException if any of the superclasses can't be found
    136     */
    137    public static JavaClass[] getSuperClasses( final JavaClass clazz ) throws ClassNotFoundException {
    138        return clazz.getSuperClasses();
    139    }
    140
    141
    142    /**
    143     * @return list of super classes of clazz in ascending order, i.e.,
    144     * Object is always the last element.
    145     * @throws ClassNotFoundException if the named class or any of its
    146     *  superclasses can't be found
    147     */
    148    public static JavaClass[] getSuperClasses( final String class_name ) throws ClassNotFoundException {
    149        final JavaClass jc = lookupClass(class_name);
    150        return getSuperClasses(jc);
    151    }
    152
    153
    154    /**
    155     * @return all interfaces implemented by class and its super
    156     * classes and the interfaces that those interfaces extend, and so on.
    157     * (Some people call this a transitive hull).
    158     * @throws ClassNotFoundException if any of the class's
    159     *  superclasses or superinterfaces can't be found
    160     */
    161    public static JavaClass[] getInterfaces( final JavaClass clazz ) throws ClassNotFoundException {
    162        return clazz.getAllInterfaces();
    163    }
    164
    165
    166    /**
    167     * @return all interfaces implemented by class and its super
    168     * classes and the interfaces that extend those interfaces, and so on
    169     * @throws ClassNotFoundException if the named class can't be found,
    170     *   or if any of its superclasses or superinterfaces can't be found
    171     */
    172    public static JavaClass[] getInterfaces( final String class_name ) throws ClassNotFoundException {
    173        return getInterfaces(lookupClass(class_name));
    174    }
    175
    176
    177    /**
    178     * Equivalent to runtime "instanceof" operator.
    179     * @return true, if clazz is an instance of super_class
    180     * @throws ClassNotFoundException if any superclasses or superinterfaces
    181     *   of clazz can't be found
    182     */
    183    public static boolean instanceOf( final JavaClass clazz, final JavaClass super_class )
    184            throws ClassNotFoundException {
    185        return clazz.instanceOf(super_class);
    186    }
    187
    188
    189    /**
    190     * @return true, if clazz is an instance of super_class
    191     * @throws ClassNotFoundException if either clazz or super_class
    192     *   can't be found
    193     */
    194    public static boolean instanceOf( final String clazz, final String super_class )
    195            throws ClassNotFoundException {
    196        return instanceOf(lookupClass(clazz), lookupClass(super_class));
    197    }
    198
    199
    200    /**
    201     * @return true, if clazz is an instance of super_class
    202     * @throws ClassNotFoundException if super_class can't be found
    203     */
    204    public static boolean instanceOf( final JavaClass clazz, final String super_class )
    205            throws ClassNotFoundException {
    206        return instanceOf(clazz, lookupClass(super_class));
    207    }
    208
    209
    210    /**
    211     * @return true, if clazz is an instance of super_class
    212     * @throws ClassNotFoundException if clazz can't be found
    213     */
    214    public static boolean instanceOf( final String clazz, final JavaClass super_class )
    215            throws ClassNotFoundException {
    216        return instanceOf(lookupClass(clazz), super_class);
    217    }
    218
    219
    220    /**
    221     * @return true, if clazz is an implementation of interface inter
    222     * @throws ClassNotFoundException if any superclasses or superinterfaces
    223     *   of clazz can't be found
    224     */
    225    public static boolean implementationOf( final JavaClass clazz, final JavaClass inter )
    226            throws ClassNotFoundException {
    227        return clazz.implementationOf(inter);
    228    }
    229
    230
    231    /**
    232     * @return true, if clazz is an implementation of interface inter
    233     * @throws ClassNotFoundException if clazz, inter, or any superclasses
    234     *   or superinterfaces of clazz can't be found
    235     */
    236    public static boolean implementationOf( final String clazz, final String inter )
    237            throws ClassNotFoundException {
    238        return implementationOf(lookupClass(clazz), lookupClass(inter));
    239    }
    240
    241
    242    /**
    243     * @return true, if clazz is an implementation of interface inter
    244     * @throws ClassNotFoundException if inter or any superclasses
    245     *   or superinterfaces of clazz can't be found
    246     */
    247    public static boolean implementationOf( final JavaClass clazz, final String inter )
    248            throws ClassNotFoundException {
    249        return implementationOf(clazz, lookupClass(inter));
    250    }
    251
    252
    253    /**
    254     * @return true, if clazz is an implementation of interface inter
    255     * @throws ClassNotFoundException if clazz or any superclasses or
    256     *   superinterfaces of clazz can't be found
    257     */
    258    public static boolean implementationOf( final String clazz, final JavaClass inter )
    259            throws ClassNotFoundException {
    260        return implementationOf(lookupClass(clazz), inter);
    261    }
    262}