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