169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.BufferedInputStream;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.File;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.InputStream;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.OutputStream;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.lang.reflect.Method;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.net.URL;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.AccessController;
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.PrivilegedActionException;
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.PrivilegedExceptionAction;
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.security.ProtectionDomain;
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Hashtable;
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Iterator;
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.ArrayList;
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Enumeration;
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Descriptor;
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A container of <code>CtClass</code> objects.
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A <code>CtClass</code> object must be obtained from this object.
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If <code>get()</code> is called on this object,
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * it searches various sources represented by <code>ClassPath</code>
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to find a class file and then it creates a <code>CtClass</code> object
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * representing that class file.  The created object is returned to the
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * caller.
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><b>Memory consumption memo:</b>
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><code>ClassPool</code> objects hold all the <code>CtClass</code>es
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * that have been created so that the consistency among modified classes
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * can be guaranteed.  Thus if a large number of <code>CtClass</code>es
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * are processed, the <code>ClassPool</code> will consume a huge amount
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * of memory.  To avoid this, a <code>ClassPool</code> object
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * should be recreated, for example, every hundred classes processed.
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Note that <code>getDefault()</code> is a singleton factory.
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Otherwise, <code>detach()</code> in <code>CtClass</code> should be used
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to avoid huge memory consumption.
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><b><code>ClassPool</code> hierarchy:</b>
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p><code>ClassPool</code>s can make a parent-child hierarchy as
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>java.lang.ClassLoader</code>s.  If a <code>ClassPool</code> has
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a parent pool, <code>get()</code> first asks the parent pool to find
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a class file.  Only if the parent could not find the class file,
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>get()</code> searches the <code>ClassPath</code>s of
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the child <code>ClassPool</code>.  This search order is reversed if
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>ClassPath.childFirstLookup</code> is <code>true</code>.
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.CtClass
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.ClassPath
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ClassPool {
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    // used by toClass().
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static java.lang.reflect.Method defineClass1, defineClass2;
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    static {
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            AccessController.doPrivileged(new PrivilegedExceptionAction(){
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                public Object run() throws Exception{
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    Class cl = Class.forName("java.lang.ClassLoader");
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    defineClass1 = cl.getDeclaredMethod("defineClass",
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            new Class[] { String.class, byte[].class,
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                         int.class, int.class });
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    defineClass2 = cl.getDeclaredMethod("defineClass",
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                           new Class[] { String.class, byte[].class,
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                 int.class, int.class, ProtectionDomain.class });
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return null;
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            });
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (PrivilegedActionException pae) {
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException("cannot initialize ClassPool", pae.getException());
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Determines the search order.
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If this field is true, <code>get()</code> first searches the
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class path associated to this <code>ClassPool</code> and then
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the class path associated with the parent <code>ClassPool</code>.
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Otherwise, the class path associated with the parent is searched
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * first.
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The default value is false.
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public boolean childFirstLookup = false;
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Turning the automatic pruning on/off.
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If this field is true, <code>CtClass</code> objects are
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * automatically pruned by default when <code>toBytecode()</code> etc.
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * are called.  The automatic pruning can be turned on/off individually
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * for each <code>CtClass</code> object.
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The initial value is false.
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see CtClass#prune()
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see CtClass#stopPruning(boolean)
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see CtClass#detach()
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static boolean doPruning = false;
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int compressCount;
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final int COMPRESS_THRESHOLD = 100;
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* releaseUnmodifiedClassFile was introduced for avoiding a bug
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       of JBoss AOP.  So the value should be true except for JBoss AOP.
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If true, unmodified and not-recently-used class files are
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * periodically released for saving memory.
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The initial value is true.
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static boolean releaseUnmodifiedClassFile = true;
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ClassPoolTail source;
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected ClassPool parent;
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected Hashtable classes;        // should be synchronous
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Table of registered cflow variables.
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Hashtable cflow = null;     // should be synchronous.
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final int INIT_HASH_SIZE = 191;
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private ArrayList importedPackages;
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a root class pool.  No parent class pool is specified.
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPool() {
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this(null);
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a root class pool.  If <code>useDefaultPath</code> is
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * true, <code>appendSystemPath()</code> is called.  Otherwise,
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * this constructor is equivalent to the constructor taking no
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * parameter.
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param useDefaultPath    true if the system search path is
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          appended.
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPool(boolean useDefaultPath) {
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this(null);
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (useDefaultPath)
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            appendSystemPath();
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a class pool.
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param parent    the parent of this class pool.  If this is a root
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                  class pool, this parameter must be <code>null</code>.
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ClassPool#getDefault()
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPool(ClassPool parent) {
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.classes = new Hashtable(INIT_HASH_SIZE);
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.source = new ClassPoolTail();
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.parent = parent;
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (parent == null) {
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            CtClass[] pt = CtClass.primitiveTypes;
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < pt.length; ++i)
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                classes.put(pt[i].getName(), pt[i]);
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.cflow = null;
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.compressCount = 0;
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        clearImportedPackages();
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the default class pool.
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The returned object is always identical since this method is
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * a singleton factory.
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The default class pool searches the system search path,
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * which usually includes the platform library, extension
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * libraries, and the search path specified by the
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>-classpath</code> option or the <code>CLASSPATH</code>
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * environment variable.
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>When this method is called for the first time, the default
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class pool is created with the following code snippet:
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <ul><code>ClassPool cp = new ClassPool();
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * cp.appendSystemPath();
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * </code></ul>
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If the default class pool cannot find any class files,
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * try <code>ClassClassPath</code> and <code>LoaderClassPath</code>.
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see ClassClassPath
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see LoaderClassPath
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static synchronized ClassPool getDefault() {
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (defaultPool == null) {
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            defaultPool = new ClassPool(null);
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            defaultPool.appendSystemPath();
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return defaultPool;
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static ClassPool defaultPool = null;
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Provide a hook so that subclasses can do their own
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * caching of classes.
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #cacheCtClass(String,CtClass,boolean)
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #removeCached(String)
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected CtClass getCached(String classname) {
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return (CtClass)classes.get(classname);
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Provides a hook so that subclasses can do their own
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * caching of classes.
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #getCached(String)
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #removeCached(String,CtClass)
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected void cacheCtClass(String classname, CtClass c, boolean dynamic) {
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classes.put(classname, c);
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Provide a hook so that subclasses can do their own
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * caching of classes.
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #getCached(String)
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #cacheCtClass(String,CtClass,boolean)
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected CtClass removeCached(String classname) {
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return (CtClass)classes.remove(classname);
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns the class search path.
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public String toString() {
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.toString();
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method is periodically invoked so that memory
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * footprint will be minimized.
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void compress() {
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (compressCount++ > COMPRESS_THRESHOLD) {
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            compressCount = 0;
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Enumeration e = classes.elements();
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            while (e.hasMoreElements())
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                ((CtClass)e.nextElement()).compress();
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Record a package name so that the Javassist compiler searches
28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the package to resolve a class name.
28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Don't record the <code>java.lang</code> package, which has
28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * been implicitly recorded by default.
28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>Since version 3.14, <code>packageName</code> can be a
29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * fully-qualified class name.
29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>Note that <code>get()</code> in <code>ClassPool</code> does
29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * not search the recorded package.  Only the compiler searches it.
29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param packageName       the package name.
29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *         It must not include the last '.' (dot).
29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *         For example, "java.util" is valid but "java.util." is wrong.
29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.1
29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void importPackage(String packageName) {
30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        importedPackages.add(packageName);
30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Clear all the package names recorded by <code>importPackage()</code>.
30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The <code>java.lang</code> package is not removed.
30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #importPackage(String)
30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.1
31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void clearImportedPackages() {
31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        importedPackages = new ArrayList();
31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        importedPackages.add("java.lang");
31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns all the package names recorded by <code>importPackage()</code>.
31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #importPackage(String)
32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.1
32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Iterator getImportedPackages() {
32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return importedPackages.iterator();
32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Records a name that never exists.
32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * For example, a package name can be recorded by this method.
32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This would improve execution performance
33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * since <code>get()</code> does not search the class path at all
33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * if the given name is an invalid name recorded by this method.
33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Note that searching the class path takes relatively long time.
33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name          a class name (separeted by dot).
33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void recordInvalidClassName(String name) {
33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        source.recordInvalidClassName(name);
33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Records the <code>$cflow</code> variable for the field specified
34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * by <code>cname</code> and <code>fname</code>.
34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name      variable name
34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cname     class name
34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param fname     field name
34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void recordCflow(String name, String cname, String fname) {
34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (cflow == null)
35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cflow = new Hashtable();
35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cflow.put(name, new Object[] { cname, fname });
35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Undocumented method.  Do not use; internal-use only.
35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name      the name of <code>$cflow</code> variable
35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Object[] lookupCflow(String name) {
36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (cflow == null)
36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cflow = new Hashtable();
36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return (Object[])cflow.get(name);
36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Reads a class file and constructs a <code>CtClass</code>
36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * object with a new name.
37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method is useful if you want to generate a new class as a copy
37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * of another class (except the class name).  For example,
37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <ul><pre>
37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * getAndRename("Point", "Pair")
37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * </pre></ul>
37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * returns a <code>CtClass</code> object representing <code>Pair</code>
37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class.  The definition of <code>Pair</code> is the same as that of
37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>Point</code> class except the class name since <code>Pair</code>
38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * is defined by reading <code>Point.class</code>.
38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param orgName   the original (fully-qualified) class name
38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param newName   the new class name
38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass getAndRename(String orgName, String newName)
38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException
38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = get0(orgName, false);
38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null)
39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new NotFoundException(orgName);
39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz instanceof CtClassType)
39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ((CtClassType)clazz).setClassPool(this);
39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        clazz.setName(newName);         // indirectly calls
39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                        // classNameChanged() in this class
39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /*
40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method is invoked by CtClassType.setName().  It removes a
40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * CtClass object from the hash table and inserts it with the new
40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * name.  Don't delegate to the parent.
40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    synchronized void classNameChanged(String oldname, CtClass clazz) {
40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass c = (CtClass)getCached(oldname);
40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (c == clazz)             // must check this equation.
40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            removeCached(oldname);  // see getAndRename().
40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String newName = clazz.getName();
41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkNotFrozen(newName);
41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cacheCtClass(newName, clazz, false);
41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Reads a class file from the source and returns a reference
41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * to the <code>CtClass</code>
41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * object representing that class file.  If that class file has been
41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * already read, this method returns a reference to the
42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>CtClass</code> created when that class file was read at the
42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * first time.
42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If <code>classname</code> ends with "[]", then this method
42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * returns a <code>CtClass</code> object for that array type.
42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>To obtain an inner class, use "$" instead of "." for separating
42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the enclosing class name and the inner class name.
42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname         a fully-qualified class name.
43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass get(String classname) throws NotFoundException {
43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz;
43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classname == null)
43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = null;
43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = get0(classname, true);
43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null)
43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new NotFoundException(classname);
44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else {
44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz.incGetCounter();
44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return clazz;
44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Reads a class file from the source and returns a reference
44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * to the <code>CtClass</code>
44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * object representing that class file.
45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method is equivalent to <code>get</code> except
45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * that it returns <code>null</code> when a class file is
45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * not found and it never throws an exception.
45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname     a fully-qualified class name.
45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return a <code>CtClass</code> object or <code>null</code>.
45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #get(String)
45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #find(String)
45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.13
45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass getOrNull(String classname) {
46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = null;
46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classname == null)
46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = null;
46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                /* ClassPool.get0() never throws an exception
46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                   but its subclass may implement get0 that
46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                   may throw an exception.
46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                */
47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                clazz = get0(classname, true);
47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (NotFoundException e){}
47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz != null)
47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz.incGetCounter();
47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns a <code>CtClass</code> object with the given name.
48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This is almost equivalent to <code>get(String)</code> except
48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * that classname can be an array-type "descriptor" (an encoded
48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * type name) such as <code>[Ljava/lang/Object;</code>.
48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>Using this method is not recommended; this method should be
48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * used only to obtain the <code>CtClass</code> object
48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * with a name returned from <code>getClassInfo</code> in
48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>javassist.bytecode.ClassPool</code>.  <code>getClassInfo</code>
49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * returns a fully-qualified class name but, if the class is an array
49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * type, it returns a descriptor.
49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname         a fully-qualified class name or a descriptor
49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          representing an array type.
49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #get(String)
49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.bytecode.ConstPool#getClassInfo(int)
49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.bytecode.Descriptor#toCtClass(String, ClassPool)
49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.8.1
49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass getCtClass(String classname) throws NotFoundException {
50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classname.charAt(0) == '[')
50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return Descriptor.toCtClass(classname, this);
50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return get(classname);
50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param useCache      false if the cached CtClass must be ignored.
50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param searchParent  false if the parent class pool is not searched.
51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return null     if the class could not be found.
51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected synchronized CtClass get0(String classname, boolean useCache)
51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException
51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = null;
51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (useCache) {
51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = getCached(classname);
51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (clazz != null)
51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return clazz;
52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (!childFirstLookup && parent != null) {
52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = parent.get0(classname, useCache);
52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (clazz != null)
52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return clazz;
52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        clazz = createCtClass(classname, useCache);
52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz != null) {
53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // clazz.getName() != classname if classname is "[L<name>;".
53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (useCache)
53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                cacheCtClass(clazz.getName(), clazz, false);
53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return clazz;
53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (childFirstLookup && parent != null)
53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            clazz = parent.get0(classname, useCache);
53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a CtClass object representing the specified class.
54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * It first examines whether or not the corresponding class
54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * file exists.  If yes, it creates a CtClass object.
54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return null if the class file could not be found.
54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected CtClass createCtClass(String classname, boolean useCache) {
55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // accept "[L<class name>;" as a class name.
55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classname.charAt(0) == '[')
55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            classname = Descriptor.toClassName(classname);
55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classname.endsWith("[]")) {
55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String base = classname.substring(0, classname.indexOf('['));
55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if ((!useCache || getCached(base) == null) && find(base) == null)
55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return null;
55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return new CtArray(classname, this);
56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (find(classname) == null)
56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return null;
56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return new CtClassType(classname, this);
56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Searches the class path to obtain the URL of the class file
57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * specified by classname.  It is also used to determine whether
57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the class file exists.
57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname     a fully-qualified class name.
57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return null if the class file could not be found.
57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see CtClass#getURL()
57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public URL find(String classname) {
57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.find(classname);
58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /*
58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Is invoked by CtClassType.setName() and methods in this class.
58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method throws an exception if the class is already frozen or
58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * if this class pool cannot edit the class since it is in a parent
58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class pool.
58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see checkNotExists(String)
58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void checkNotFrozen(String classname) throws RuntimeException {
59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = getCached(classname);
59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null) {
59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (!childFirstLookup && parent != null) {
59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                try {
59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    clazz = parent.get0(classname, true);
59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                catch (NotFoundException e) {}
59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (clazz != null)
59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new RuntimeException(classname
60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            + " is in a parent ClassPool.  Use the parent.");
60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (clazz.isFrozen())
60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException(classname
60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                        + ": frozen class (cannot edit)");
60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /*
61069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method returns null if this or its parent class pool does
61169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * not contain a CtClass object with the class name.
61269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
61369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see checkNotFrozen(String)
61469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
61569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    CtClass checkNotExists(String classname) {
61669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = getCached(classname);
61769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (clazz == null)
61869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (!childFirstLookup && parent != null) {
61969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                try {
62069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    clazz = parent.get0(classname, true);
62169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
62269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                catch (NotFoundException e) {}
62369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
62469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
62569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
62669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
62769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
62869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* for CtClassType.getClassFile2().  Don't delegate to the parent.
62969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
63069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    InputStream openClassfile(String classname) throws NotFoundException {
63169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.openClassfile(classname);
63269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
63369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
63469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    void writeClassfile(String classname, OutputStream out)
63569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException, IOException, CannotCompileException
63669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
63769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        source.writeClassfile(classname, out);
63869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
63969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
64069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
64169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Reads class files from the source and returns an array of
64269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>CtClass</code>
64369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * objects representing those class files.
64469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
64569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If an element of <code>classnames</code> ends with "[]",
64669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * then this method
64769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * returns a <code>CtClass</code> object for that array type.
64869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
64969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classnames        an array of fully-qualified class name.
65069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
65169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass[] get(String[] classnames) throws NotFoundException {
65269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (classnames == null)
65369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new CtClass[0];
65469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
65569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int num = classnames.length;
65669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass[] result = new CtClass[num];
65769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < num; ++i)
65869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            result[i] = get(classnames[i]);
65969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
66069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return result;
66169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
66269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
66369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
66469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Reads a class file and obtains a compile-time method.
66569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
66669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname         the class name
66769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param methodname        the method name
66869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see CtClass#getDeclaredMethod(String)
66969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
67069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtMethod getMethod(String classname, String methodname)
67169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException
67269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
67369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass c = get(classname);
67469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return c.getDeclaredMethod(methodname);
67569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
67669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
67769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
67869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new class (or interface) from the given class file.
67969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class with the same name, the new class
68069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * overwrites that previous class.
68169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
68269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>This method is used for creating a <code>CtClass</code> object
68369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * directly from a class file.  The qualified class name is obtained
68469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * from the class file; you do not have to explicitly give the name.
68569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
68669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classfile class file.
68769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws RuntimeException if there is a frozen class with the
68869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          the same name.
68969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #makeClassIfNew(InputStream)
69069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ByteArrayClassPath
69169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
69269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass makeClass(InputStream classfile)
69369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws IOException, RuntimeException
69469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
69569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return makeClass(classfile, true);
69669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
69769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
69869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
69969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new class (or interface) from the given class file.
70069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class with the same name, the new class
70169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * overwrites that previous class.
70269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
70369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>This method is used for creating a <code>CtClass</code> object
70469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * directly from a class file.  The qualified class name is obtained
70569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * from the class file; you do not have to explicitly give the name.
70669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
70769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classfile class file.
70869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param ifNotFrozen       throws a RuntimeException if this parameter is true
70969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          and there is a frozen class with the same name.
71069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ByteArrayClassPath
71169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
71269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass makeClass(InputStream classfile, boolean ifNotFrozen)
71369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws IOException, RuntimeException
71469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
71569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        compress();
71669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classfile = new BufferedInputStream(classfile);
71769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = new CtClassType(classfile, this);
71869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        clazz.checkModify();
71969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String classname = clazz.getName();
72069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (ifNotFrozen)
72169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            checkNotFrozen(classname);
72269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
72369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cacheCtClass(classname, clazz, true);
72469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
72569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
72669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
72769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
72869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new class (or interface) from the given class file.
72969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class with the same name, this method
73069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * returns the existing class; a new class is never created from
73169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the given class file.
73269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
73369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>This method is used for creating a <code>CtClass</code> object
73469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * directly from a class file.  The qualified class name is obtained
73569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * from the class file; you do not have to explicitly give the name.
73669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
73769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classfile             the class file.
73869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #makeClass(InputStream)
73969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ByteArrayClassPath
74069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.9
74169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
74269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass makeClassIfNew(InputStream classfile)
74369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws IOException, RuntimeException
74469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
74569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        compress();
74669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classfile = new BufferedInputStream(classfile);
74769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = new CtClassType(classfile, this);
74869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        clazz.checkModify();
74969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String classname = clazz.getName();
75069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass found = checkNotExists(classname);
75169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (found != null)
75269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return found;
75369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else {
75469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cacheCtClass(classname, clazz, true);
75569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return clazz;
75669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
75769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
75869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
75969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
76069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new public class.
76169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class with the same name, the new class
76269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * overwrites that previous class.
76369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
76469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If no constructor is explicitly added to the created new
76569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class, Javassist generates constructors and adds it when
76669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the class file is generated.  It generates a new constructor
76769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * for each constructor of the super class.  The new constructor
76869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * takes the same set of parameters and invokes the
76969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * corresponding constructor of the super class.  All the received
77069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * parameters are passed to it.
77169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
77269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname                 a fully-qualified class name.
77369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws RuntimeException         if the existing class is frozen.
77469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
77569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass makeClass(String classname) throws RuntimeException {
77669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return makeClass(classname, null);
77769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
77869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
77969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
78069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new public class.
78169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class/interface with the same name,
78269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the new class overwrites that previous class.
78369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
78469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>If no constructor is explicitly added to the created new
78569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class, Javassist generates constructors and adds it when
78669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the class file is generated.  It generates a new constructor
78769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * for each constructor of the super class.  The new constructor
78869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * takes the same set of parameters and invokes the
78969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * corresponding constructor of the super class.  All the received
79069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * parameters are passed to it.
79169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
79269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname  a fully-qualified class name.
79369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param superclass the super class.
79469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws RuntimeException if the existing class is frozen.
79569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
79669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public synchronized CtClass makeClass(String classname, CtClass superclass)
79769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws RuntimeException
79869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
79969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkNotFrozen(classname);
80069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = new CtNewClass(classname, this, false, superclass);
80169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cacheCtClass(classname, clazz, true);
80269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
80369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
80469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
80569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
80669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new public nested class.
80769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This method is called by CtClassType.makeNestedClass().
80869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
80969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param classname     a fully-qualified class name.
81069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return      the nested class.
81169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
81269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    synchronized CtClass makeNestedClass(String classname) {
81369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkNotFrozen(classname);
81469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = new CtNewNestedClass(classname, this, false, null);
81569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cacheCtClass(classname, clazz, true);
81669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
81769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
81869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
81969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
82069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new public interface.
82169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class/interface with the same name,
82269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the new interface overwrites that previous one.
82369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
82469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name          a fully-qualified interface name.
82569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws RuntimeException if the existing interface is frozen.
82669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
82769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public CtClass makeInterface(String name) throws RuntimeException {
82869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return makeInterface(name, null);
82969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
83069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
83169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
83269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Creates a new public interface.
83369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If there already exists a class/interface with the same name,
83469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the new interface overwrites that previous one.
83569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
83669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name       a fully-qualified interface name.
83769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param superclass the super interface.
83869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws RuntimeException if the existing interface is frozen.
83969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
84069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public synchronized CtClass makeInterface(String name, CtClass superclass)
84169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws RuntimeException
84269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
84369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        checkNotFrozen(name);
84469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = new CtNewClass(name, this, true, superclass);
84569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        cacheCtClass(name, clazz, true);
84669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz;
84769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
84869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
84969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
85069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Appends the system search path to the end of the
85169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * search path.  The system search path
85269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * usually includes the platform library, extension
85369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * libraries, and the search path specified by the
85469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>-classpath</code> option or the <code>CLASSPATH</code>
85569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * environment variable.
85669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
85769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the appended class path.
85869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
85969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPath appendSystemPath() {
86069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.appendSystemPath();
86169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
86269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
86369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
86469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Insert a <code>ClassPath</code> object at the head of the
86569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * search path.
86669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
86769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the inserted class path.
86869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ClassPath
86969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.URLClassPath
87069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ByteArrayClassPath
87169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
87269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPath insertClassPath(ClassPath cp) {
87369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.insertClassPath(cp);
87469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
87569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
87669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
87769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Appends a <code>ClassPath</code> object to the end of the
87869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * search path.
87969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
88069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the appended class path.
88169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ClassPath
88269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.URLClassPath
88369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.ByteArrayClassPath
88469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
88569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPath appendClassPath(ClassPath cp) {
88669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.appendClassPath(cp);
88769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
88869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
88969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
89069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Inserts a directory or a jar (or zip) file at the head of the
89169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * search path.
89269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
89369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pathname      the path name of the directory or jar file.
89469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      It must not end with a path separator ("/").
89569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      If the path name ends with "/*", then all the
89669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      jar files matching the path name are inserted.
89769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
89869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the inserted class path.
89969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws NotFoundException    if the jar file is not found.
90069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
90169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPath insertClassPath(String pathname)
90269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException
90369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
90469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.insertClassPath(pathname);
90569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
90669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
90769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
90869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Appends a directory or a jar (or zip) file to the end of the
90969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * search path.
91069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
91169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pathname the path name of the directory or jar file.
91269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                 It must not end with a path separator ("/").
91369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      If the path name ends with "/*", then all the
91469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      jar files matching the path name are appended.
91569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
91669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the appended class path.
91769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws NotFoundException if the jar file is not found.
91869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
91969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassPath appendClassPath(String pathname)
92069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws NotFoundException
92169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
92269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return source.appendClassPath(pathname);
92369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
92469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
92569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
92669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Detatches the <code>ClassPath</code> object from the search path.
92769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The detached <code>ClassPath</code> object cannot be added
92869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * to the pathagain.
92969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
93069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void removeClassPath(ClassPath cp) {
93169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        source.removeClassPath(cp);
93269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
93369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
93469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
93569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Appends directories and jar files for search.
93669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
93769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The elements of the given path list must be separated by colons
93869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * in Unix or semi-colons in Windows.
93969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
94069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param pathlist      a (semi)colon-separated list of
94169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      the path names of directories and jar files.
94269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      The directory name must not end with a path
94369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      separator ("/").
94469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @throws NotFoundException if a jar file is not found.
94569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
94669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void appendPathList(String pathlist) throws NotFoundException {
94769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        char sep = File.pathSeparatorChar;
94869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int i = 0;
94969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (;;) {
95069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int j = pathlist.indexOf(sep, i);
95169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (j < 0) {
95269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                appendClassPath(pathlist.substring(i));
95369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
95469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
95569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else {
95669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                appendClassPath(pathlist.substring(i, j));
95769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                i = j + 1;
95869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
95969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
96069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
96169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
96269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
96369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Converts the given class to a <code>java.lang.Class</code> object.
96469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Once this method is called, further modifications are not
96569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * allowed any more.
96669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * To load the class, this method uses the context class loader
96769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * of the current thread.  It is obtained by calling
96869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>getClassLoader()</code>.
96969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
97069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>This behavior can be changed by subclassing the pool and changing
97169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the <code>getClassLoader()</code> method.
97269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * If the program is running on some application
97369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * server, the context class loader might be inappropriate to load the
97469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class.
97569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
97669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>This method is provided for convenience.  If you need more
97769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * complex functionality, you should write your own class loader.
97869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
97969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p><b>Warining:</b> A Class object returned by this method may not
98069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * work with a security manager or a signed jar file because a
98169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * protection domain is not specified.
98269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
98369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #toClass(CtClass, java.lang.ClassLoader, ProtectionDomain)
98469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #getClassLoader()
98569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
98669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Class toClass(CtClass clazz) throws CannotCompileException {
98769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // Some subclasses of ClassPool may override toClass(CtClass,ClassLoader).
98869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // So we should call that method instead of toClass(.., ProtectionDomain).
98969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return toClass(clazz, getClassLoader());
99069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
99169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
99269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
99369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Get the classloader for <code>toClass()</code>, <code>getAnnotations()</code> in
99469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>CtClass</code>, etc.
99569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
99669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The default is the context class loader.
99769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
99869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return the classloader for the pool
99969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #toClass(CtClass)
100069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see CtClass#getAnnotations()
100169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
100269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public ClassLoader getClassLoader() {
100369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return getContextClassLoader();
100469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
100569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
100669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
100769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Obtains a class loader that seems appropriate to look up a class
100869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * by name.
100969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
101069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    static ClassLoader getContextClassLoader() {
101169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return Thread.currentThread().getContextClassLoader();
101269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
101369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
101469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
101569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Converts the class to a <code>java.lang.Class</code> object.
101669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Do not override this method any more at a subclass because
101769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>toClass(CtClass)</code> never calls this method.
101869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
101969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p><b>Warining:</b> A Class object returned by this method may not
102069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * work with a security manager or a signed jar file because a
102169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * protection domain is not specified.
102269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
102369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @deprecated      Replaced by {@link #toClass(CtClass,ClassLoader,ProtectionDomain)}.
102469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * A subclass of <code>ClassPool</code> that has been
102569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * overriding this method should be modified.  It should override
102669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * {@link #toClass(CtClass,ClassLoader,ProtectionDomain)}.
102769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
102869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Class toClass(CtClass ct, ClassLoader loader)
102969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException
103069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
103169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return toClass(ct, loader, null);
103269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
103369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
103469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
103569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Converts the class to a <code>java.lang.Class</code> object.
103669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Once this method is called, further modifications are not allowed
103769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * any more.
103869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
103969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>The class file represented by the given <code>CtClass</code> is
104069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * loaded by the given class loader to construct a
104169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <code>java.lang.Class</code> object.  Since a private method
104269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * on the class loader is invoked through the reflection API,
104369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the caller must have permissions to do that.
104469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
104569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>An easy way to obtain <code>ProtectionDomain</code> object is
104669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * to call <code>getProtectionDomain()</code>
104769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * in <code>java.lang.Class</code>.  It returns the domain that the
104869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * class belongs to.
104969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
105069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * <p>This method is provided for convenience.  If you need more
105169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * complex functionality, you should write your own class loader.
105269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
105369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param loader        the class loader used to load this class.
105469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      For example, the loader returned by
105569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      <code>getClassLoader()</code> can be used
105669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      for this parameter.
105769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param domain        the protection domain for the class.
105869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      If it is null, the default domain created
105969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      by <code>java.lang.ClassLoader</code> is used.
106069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
106169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #getClassLoader()
106269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @since 3.3
106369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
106469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain)
106569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException
106669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
106769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
106869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            byte[] b = ct.toBytecode();
106969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            java.lang.reflect.Method method;
107069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Object[] args;
107169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (domain == null) {
107269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                method = defineClass1;
107369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                args = new Object[] { ct.getName(), b, new Integer(0),
107469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                      new Integer(b.length)};
107569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
107669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else {
107769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                method = defineClass2;
107869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                args = new Object[] { ct.getName(), b, new Integer(0),
107969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    new Integer(b.length), domain};
108069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
108169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
108269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return toClass2(method, loader, args);
108369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
108469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (RuntimeException e) {
108569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw e;
108669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
108769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (java.lang.reflect.InvocationTargetException e) {
108869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new CannotCompileException(e.getTargetException());
108969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
109069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (Exception e) {
109169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new CannotCompileException(e);
109269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
109369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
109469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
109569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static synchronized Class toClass2(Method method,
109669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ClassLoader loader, Object[] args)
109769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws Exception
109869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
109969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        method.setAccessible(true);
110069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
110169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return (Class)method.invoke(loader, args);
110269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
110369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        finally {
110469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            method.setAccessible(false);
110569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
110669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
110769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
1108