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