org.apache.cxf.common.util.ASMHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-jaxrs Show documentation
Show all versions of cxf-bundle-jaxrs Show documentation
Apache CXF JAX-RS Bundle Jar
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.common.util;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.objectweb.asm.ClassWriter;
public class ASMHelper {
protected static final Map, String> PRIMITIVE_MAP = new HashMap, String>();
protected static final Map, String> NONPRIMITIVE_MAP = new HashMap, String>();
protected static final Map, WeakReference> LOADER_MAP
= new WeakIdentityHashMap, WeakReference>();
protected static boolean oldASM;
static {
PRIMITIVE_MAP.put(Byte.TYPE, "B");
PRIMITIVE_MAP.put(Boolean.TYPE, "Z");
PRIMITIVE_MAP.put(Long.TYPE, "J");
PRIMITIVE_MAP.put(Integer.TYPE, "I");
PRIMITIVE_MAP.put(Short.TYPE, "S");
PRIMITIVE_MAP.put(Character.TYPE, "C");
PRIMITIVE_MAP.put(Float.TYPE, "F");
PRIMITIVE_MAP.put(Double.TYPE, "D");
NONPRIMITIVE_MAP.put(Byte.TYPE, Byte.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Boolean.TYPE, Boolean.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Long.TYPE, Long.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Integer.TYPE, Integer.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Short.TYPE, Short.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Character.TYPE, Character.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Float.TYPE, Float.class.getName().replaceAll("\\.", "/"));
NONPRIMITIVE_MAP.put(Double.TYPE, Double.class.getName().replaceAll("\\.", "/"));
}
protected static String getMethodSignature(Method m) {
StringBuilder buf = new StringBuilder("(");
for (Class> cl : m.getParameterTypes()) {
buf.append(getClassCode(cl));
}
buf.append(")");
buf.append(getClassCode(m.getReturnType()));
return buf.toString();
}
protected static String periodToSlashes(String s) {
char ch[] = s.toCharArray();
for (int x = 0; x < ch.length; x++) {
if (ch[x] == '.') {
ch[x] = '/';
}
}
return new String(ch);
}
public static String getClassCode(Class> cl) {
if (cl == Void.TYPE) {
return "V";
}
if (cl.isPrimitive()) {
return PRIMITIVE_MAP.get(cl);
}
if (cl.isArray()) {
return "[" + getClassCode(cl.getComponentType());
}
return "L" + periodToSlashes(cl.getName()) + ";";
}
public static String getClassCode(Type type) {
if (type instanceof Class) {
return getClassCode((Class)type);
} else if (type instanceof GenericArrayType) {
GenericArrayType at = (GenericArrayType)type;
return "[" + getClassCode(at.getGenericComponentType());
} else if (type instanceof TypeVariable) {
TypeVariable tv = (TypeVariable)type;
Type[] bounds = tv.getBounds();
if (bounds != null && bounds.length == 1) {
return getClassCode(bounds[0]);
} else {
throw new IllegalArgumentException("Unable to determine type for: " + tv);
}
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType)type;
StringBuilder a = new StringBuilder(getClassCode(pt.getRawType()));
a.setLength(a.length() - 1);
a.append('<');
for (Type t : pt.getActualTypeArguments()) {
a.append(getClassCode(t));
}
a.append(">;");
return a.toString();
} else if (type instanceof WildcardType) {
WildcardType wt = (WildcardType)type;
StringBuilder a = new StringBuilder();
Type[] lowBounds = wt.getLowerBounds();
Type[] upBounds = wt.getUpperBounds();
for (Type t : upBounds) {
a.append("+");
a.append(getClassCode(t));
}
for (Type t : lowBounds) {
a.append("-");
a.append(getClassCode(t));
}
return a.toString();
}
return null;
}
public ClassWriter createClassWriter() {
ClassWriter newCw = null;
if (!oldASM) {
Class cls;
try {
cls = ClassWriter.class;
} catch (NoClassDefFoundError error) {
throw new RuntimeException("No ASM ClassWriterFound", error);
}
try {
// ASM 1.5.x/2.x
Constructor cons = cls.getConstructor(new Class>[] {Boolean.TYPE});
try {
// got constructor, now check if it's 1.x which is very
// different from 2.x and 3.x
cls.getMethod("newConstInt", new Class>[] {Integer.TYPE});
// newConstInt was removed in 2.x, if we get this far, we're
// using 1.5.x,
// set to null so we don't attempt to use it.
newCw = null;
oldASM = true;
} catch (Throwable t) {
newCw = cons.newInstance(new Object[] {Boolean.TRUE});
}
} catch (Throwable e) {
// ASM 3.x
try {
Constructor cons = cls.getConstructor(new Class>[] {Integer.TYPE});
int i = cls.getField("COMPUTE_MAXS").getInt(null);
i |= cls.getField("COMPUTE_FRAMES").getInt(null);
newCw = cons.newInstance(new Object[] {Integer.valueOf(i)});
} catch (Throwable e1) {
// ignore
}
}
}
return newCw;
}
public Class> loadClass(String className, Class clz , byte[] bytes) {
TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
return loader.defineClass(className, bytes);
}
public Class> findClass(String className, Class clz) {
TypeHelperClassLoader loader = getTypeHelperClassLoader(clz);
return loader.lookupDefinedClass(className);
}
private static synchronized TypeHelperClassLoader getTypeHelperClassLoader(Class> l) {
WeakReference ref = LOADER_MAP.get(l);
TypeHelperClassLoader ret;
if (ref == null || ref.get() == null) {
ret = new TypeHelperClassLoader(l.getClassLoader());
LOADER_MAP.put(l, new WeakReference(ret));
} else {
ret = ref.get();
}
return ret;
}
public static class TypeHelperClassLoader extends ClassLoader {
Map> defined = new ConcurrentHashMap>();
TypeHelperClassLoader(ClassLoader parent) {
super(parent);
}
public Class> lookupDefinedClass(String name) {
return defined.get(name.replace('/', '.'));
}
public synchronized Class> defineClass(String name, byte bytes[]) {
Class> ret = defined.get(name.replace('/', '.'));
if (ret != null) {
return ret;
}
if (name.endsWith("package-info")) {
Package p = super.getPackage(name.substring(0, name.length() - 13));
if (p == null) {
definePackage(name.substring(0, name.length() - 13).replace('/', '.'),
null,
null,
null,
null,
null,
null,
null);
}
}
ret = super.defineClass(name.replace('/', '.'), bytes, 0, bytes.length);
defined.put(name.replace('/', '.'), ret);
return ret;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy