All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javassist.runtime.Desc Maven / Gradle / Ivy

There is a newer version: 3.3.8
Show newest version
/*
 * Javassist, a Java-bytecode translator toolkit.
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License.  Alternatively, the contents of this file may be used under
 * the terms of the GNU Lesser General Public License Version 2.1 or later,
 * or the Apache License Version 2.0.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 */

package javassist.runtime;

/**
 * A support class for implementing $sig and
 * $type.
 * This support class is required at runtime
 * only if $sig or $type is used.
 */
public class Desc {

    /**
     * Specifies how a java.lang.Class object is loaded.
     *
     * 

If true, it is loaded by: *

Thread.currentThread().getContextClassLoader().loadClass()
*

If false, it is loaded by Class.forName(). * The default value is false. */ public static boolean useContextClassLoader = false; private static final ThreadLocal USE_CONTEXT_CLASS_LOADER_LOCALLY = new ThreadLocal() { @Override protected Boolean initialValue() { return false; } }; /** * Changes so that the current thread will use the context class loader * when a class is loaded. * This method changes the behavior per thread unlike {@link useContextClassLoader}. * * @since 3.25 */ public static void setUseContextClassLoaderLocally() { USE_CONTEXT_CLASS_LOADER_LOCALLY.set(true); } /** * Changes so that the current thread will not use the context class loader * when a class is loaded. * Call this method before releasing the current thread for reuse. * It invokes ThreadLocal.remvoe(). * * @since 3.25 */ public static void resetUseContextClassLoaderLocally() { USE_CONTEXT_CLASS_LOADER_LOCALLY.remove(); } private static Class getClassObject(String name) throws ClassNotFoundException { if (useContextClassLoader || USE_CONTEXT_CLASS_LOADER_LOCALLY.get()) return Class.forName(name, true, Thread.currentThread().getContextClassLoader()); return Class.forName(name); } /** * Interprets the given class name. * It is used for implementing $class. */ public static Class getClazz(String name) { try { return getClassObject(name); } catch (ClassNotFoundException e) { throw new RuntimeException( "$class: internal error, could not find class '" + name + "' (Desc.useContextClassLoader: " + Boolean.toString(useContextClassLoader) + ")", e); } } /** * Interprets the given type descriptor representing a method * signature. It is used for implementing $sig. */ public static Class[] getParams(String desc) { if (desc.charAt(0) != '(') throw new RuntimeException("$sig: internal error"); return getType(desc, desc.length(), 1, 0); } /** * Interprets the given type descriptor. * It is used for implementing $type. */ public static Class getType(String desc) { Class[] result = getType(desc, desc.length(), 0, 0); if (result == null || result.length != 1) throw new RuntimeException("$type: internal error"); return result[0]; } private static Class[] getType(String desc, int descLen, int start, int num) { Class clazz; if (start >= descLen) return new Class[num]; char c = desc.charAt(start); switch (c) { case 'Z' : clazz = Boolean.TYPE; break; case 'C' : clazz = Character.TYPE; break; case 'B' : clazz = Byte.TYPE; break; case 'S' : clazz = Short.TYPE; break; case 'I' : clazz = Integer.TYPE; break; case 'J' : clazz = Long.TYPE; break; case 'F' : clazz = Float.TYPE; break; case 'D' : clazz = Double.TYPE; break; case 'V' : clazz = Void.TYPE; break; case 'L' : case '[' : return getClassType(desc, descLen, start, num); default : return new Class[num]; } Class[] result = getType(desc, descLen, start + 1, num + 1); result[num] = clazz; return result; } private static Class[] getClassType(String desc, int descLen, int start, int num) { int end = start; while (desc.charAt(end) == '[') ++end; if (desc.charAt(end) == 'L') { end = desc.indexOf(';', end); if (end < 0) throw new IndexOutOfBoundsException("bad descriptor"); } String cname; if (desc.charAt(start) == 'L') cname = desc.substring(start + 1, end); else cname = desc.substring(start, end + 1); Class[] result = getType(desc, descLen, end + 1, num + 1); try { result[num] = getClassObject(cname.replace('/', '.')); } catch (ClassNotFoundException e) { // "new RuntimeException(e)" is not available in JDK 1.3. throw new RuntimeException(e.getMessage()); } return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy