日期:2014-05-16 浏览次数:20500 次
package jsr292.cookbook.lazyinit;
import java.io.IOException;
import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.nio.ByteBuffer;
import sun.misc.BASE64Decoder;
public class RT {
@SuppressWarnings("restriction")
public static CallSite bootstrap(Lookup lookup, String name, MethodType type, String base64Array) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] bytes = decoder.decodeBuffer(base64Array);
Class<?> returnType = type.returnType();
Object value = convertAsArray(bytes, returnType);
return new ConstantCallSite(MethodHandles.constant(returnType, value));
}
private static Object convertAsArray(byte[] bytes, Class<?> returnType) {
if (returnType == byte[].class) {
return bytes;
} else
if (returnType == char[].class) {
char[] array = new char[bytes.length / 2];
ByteBuffer.wrap(bytes).asCharBuffer().get(array);
return array;
} else
if (returnType == short[].class) {
return ByteBuffer.wrap(bytes).asShortBuffer().duplicate().array();
} else
if (returnType == int[].class) {
return ByteBuffer.wrap(bytes).asIntBuffer().duplicate().array();
} else
if (returnType == long[].class) {
return ByteBuffer.wrap(bytes).asLongBuffer().duplicate().array();
} else
if (returnType == float[].class) {
return ByteBuffer.wrap(bytes).asFloatBuffer().duplicate().array();
} else
if (returnType == double[].class) {
return ByteBuffer.wrap(bytes).asDoubleBuffer().duplicate().array();
} else {
throw new BootstrapMethodError("invalid constant array type "+returnType);
}
}
}
package jsr292.cookbook.interceptors;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
//import java.util.Map;
public class Interceptors {
public static MethodHandle before(MethodHandle target, MethodHandle before) {
MethodType beforeType = before.type();
if (beforeType.returnType() != void.class) {
throw new IllegalArgumentException("before must return void "+beforeType);
}
MethodType targetType = target.type();
if (beforeType.parameterCount() != targetType.parameterCount()) {
if (beforeType.parameterCount() > targetType.parameterCount()) {
throw new IllegalArgumentException("before has too much parameter compare to target "+beforeType+" "+targetType);
}
before = MethodHandles.dropArguments(before,
beforeType.parameterCount(),
targetType.parameterList().subList(beforeType.parameterCount(), targetType.parameterCount()));
}
if (!before.type().equals(targetType.changeReturnType(void.class))) {
throw new IllegalArgumentException("before parameter types are not compatible with target "+beforeType+" "+targetType);
}
return MethodHandles.foldArguments(target, before);
}
public static MethodHandle after(MethodHandle target, MethodHandle after) {
//FIXME just use filterReturnValue instead !!, when bug fixed
MethodType afterType = after.type();
if (afterType.returnType() != void.class) {
throw new IllegalArgumentException("after must return void "+afterType);
}
MethodType targetType = target.type();
boolean voidReturnType = targetType.returnType() == v