use of javax.annotation.Resource in project jetty.project by eclipse.
the class ResourceAnnotationHandler method handleClass.
public void handleClass(Class<?> clazz) {
Resource resource = (Resource) clazz.getAnnotation(Resource.class);
if (resource != null) {
String name = resource.name();
String mappedName = resource.mappedName();
if (name == null || name.trim().equals(""))
throw new IllegalStateException("Class level Resource annotations must contain a name (Common Annotations Spec Section 2.3)");
try {
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName))
if (!org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName))
throw new IllegalStateException("No resource at " + (mappedName == null ? name : mappedName));
} catch (NamingException e) {
LOG.warn(e);
}
}
}
use of javax.annotation.Resource in project jetty.project by eclipse.
the class ResourceAnnotationHandler method handleMethod.
/**
* Process a Resource annotation on a Method.
* <p>
* This will generate a JNDI entry, and an Injection to be
* processed when an instance of the class is created.
*
* @param clazz the class to process
* @param method the method to process
*/
public void handleMethod(Class<?> clazz, Method method) {
Resource resource = (Resource) method.getAnnotation(Resource.class);
if (resource != null) {
//JavaEE Spec 5.2.3: Method cannot be static
if (Modifier.isStatic(method.getModifiers())) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": cannot be static");
return;
}
// only 1 parameter
if (!method.getName().startsWith("set")) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, does not start with 'set'");
return;
}
if (method.getParameterCount() != 1) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, not single argument to method");
return;
}
if (Void.TYPE != method.getReturnType()) {
LOG.warn("Skipping Resource annotation on " + clazz.getName() + "." + method.getName() + ": invalid java bean, not void");
return;
}
//default name is the javabean property name
String name = method.getName().substring(3);
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
name = clazz.getCanonicalName() + "/" + name;
name = (resource.name() != null && !resource.name().trim().equals("") ? resource.name() : name);
String mappedName = (resource.mappedName() != null && !resource.mappedName().trim().equals("") ? resource.mappedName() : null);
Class<?> paramType = method.getParameterTypes()[0];
Class<?> resourceType = resource.type();
//Servlet Spec 3.0 p. 76
//If a descriptor has specified at least 1 injection target for this
//resource, then it overrides this annotation
MetaData metaData = _context.getMetaData();
if (metaData.getOriginDescriptor("resource-ref." + name + ".injection") != null) {
//it overrides this annotation
return;
}
//check if an injection has already been setup for this target by web.xml
InjectionCollection injections = (InjectionCollection) _context.getAttribute(InjectionCollection.INJECTION_COLLECTION);
if (injections == null) {
injections = new InjectionCollection();
_context.setAttribute(InjectionCollection.INJECTION_COLLECTION, injections);
}
Injection injection = injections.getInjection(name, clazz, method, paramType);
if (injection == null) {
try {
//try binding name to environment
//try the webapp's environment first
boolean bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context, name, mappedName);
//try the server's environment
if (!bound)
bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(_context.getServer(), name, mappedName);
//try the jvm's environment
if (!bound)
bound = org.eclipse.jetty.plus.jndi.NamingEntryUtil.bindToENC(null, name, mappedName);
//NamingEntry, just a value bound in java:comp/env
if (!bound) {
try {
InitialContext ic = new InitialContext();
String nameInEnvironment = (mappedName != null ? mappedName : name);
ic.lookup("java:comp/env/" + nameInEnvironment);
bound = true;
} catch (NameNotFoundException e) {
bound = false;
}
}
if (bound) {
LOG.debug("Bound " + (mappedName == null ? name : mappedName) + " as " + name);
// Make the Injection for it
injection = new Injection();
injection.setTarget(clazz, method, paramType, resourceType);
injection.setJndiName(name);
injection.setMappingName(mappedName);
injections.add(injection);
//TODO - an @Resource is equivalent to a resource-ref, resource-env-ref, message-destination
metaData.setOrigin("resource-ref." + name + ".injection", resource, clazz);
} else if (!isEnvEntryType(paramType)) {
// JavaEE Spec. sec 5.4.1.3
throw new IllegalStateException("No resource at " + (mappedName == null ? name : mappedName));
}
} catch (NamingException e) {
// JavaEE Spec. sec 5.4.1.3
if (!isEnvEntryType(paramType))
throw new IllegalStateException(e);
}
}
}
}
use of javax.annotation.Resource in project spring-framework by spring-projects.
the class CommonAnnotationBeanPostProcessor method buildResourceMetadata.
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
}
currElements.add(new WebServiceRefElement(field, field, null));
} else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static fields");
}
currElements.add(new EjbRefElement(field, field, null));
} else if (field.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(field.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static fields");
}
if (!ignoredResourceTypes.contains(field.getType().getName())) {
currElements.add(new ResourceElement(field, field, null));
}
}
}
});
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
} else if (ejbRefClass != null && bridgedMethod.isAnnotationPresent(ejbRefClass)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@EJB annotation is not supported on static methods");
}
if (method.getParameterCount() != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new EjbRefElement(method, bridgedMethod, pd));
} else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
if (Modifier.isStatic(method.getModifiers())) {
throw new IllegalStateException("@Resource annotation is not supported on static methods");
}
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1) {
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
use of javax.annotation.Resource in project opennms by OpenNMS.
the class BeanUtils method assertAutowiring.
/**
* Check that all fields that are marked with @Autowired are not null.
* This will identify classes that have been loaded by Spring but have
* not been autowired via {@code <context:annotation-config />}.
*/
public static <T> void assertAutowiring(T instance) {
for (Field field : instance.getClass().getDeclaredFields()) {
Autowired autowired = field.getAnnotation(Autowired.class);
Inject inject = field.getAnnotation(Inject.class);
Resource resource = field.getAnnotation(Resource.class);
if ((autowired != null && autowired.required()) || (inject != null) || (resource != null)) {
try {
field.setAccessible(true);
notNull(field.get(instance), "@Autowired/@Inject/@Resource field " + field.getName() + " cannot be null");
LOG.debug("{} is not null", field.getName());
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Illegal access to @Autowired/@Resource field " + field.getName());
}
}
}
}
use of javax.annotation.Resource in project redkale by redkale.
the class Rest method createRestWebSocketServlet.
public static <T extends HttpServlet> T createRestWebSocketServlet(final ClassLoader classLoader, final Class<? extends WebSocket> webSocketType) {
if (webSocketType == null)
throw new RuntimeException("Rest WebSocket Class is null on createRestWebSocketServlet");
if (Modifier.isAbstract(webSocketType.getModifiers()))
throw new RuntimeException("Rest WebSocket Class(" + webSocketType + ") cannot abstract on createRestWebSocketServlet");
if (Modifier.isFinal(webSocketType.getModifiers()))
throw new RuntimeException("Rest WebSocket Class(" + webSocketType + ") cannot final on createRestWebSocketServlet");
final RestWebSocket rws = webSocketType.getAnnotation(RestWebSocket.class);
if (rws == null || rws.ignore())
throw new RuntimeException("Rest WebSocket Class(" + webSocketType + ") have not @RestWebSocket or @RestWebSocket.ignore=true on createRestWebSocketServlet");
boolean valid = false;
for (Constructor c : webSocketType.getDeclaredConstructors()) {
if (c.getParameterCount() == 0 && (Modifier.isPublic(c.getModifiers()) || Modifier.isProtected(c.getModifiers()))) {
valid = true;
break;
}
}
if (!valid)
throw new RuntimeException("Rest WebSocket Class(" + webSocketType + ") must have public or protected Constructor on createRestWebSocketServlet");
final String rwsname = ResourceFactory.formatResourceName(rws.name());
if (!checkName(rws.catalog()))
throw new RuntimeException(webSocketType.getName() + " have illegal " + RestWebSocket.class.getSimpleName() + ".catalog, only 0-9 a-z A-Z _ cannot begin 0-9");
if (!checkName(rwsname))
throw new RuntimeException(webSocketType.getName() + " have illegal " + RestWebSocket.class.getSimpleName() + ".name, only 0-9 a-z A-Z _ cannot begin 0-9");
// ----------------------------------------------------------------------------------------
final Set<Field> resourcesFieldSet = new LinkedHashSet<>();
final ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
final Set<String> resourcesFieldNameSet = new HashSet<>();
Class clzz = webSocketType;
do {
for (Field field : clzz.getDeclaredFields()) {
if (field.getAnnotation(Resource.class) == null)
continue;
if (resourcesFieldNameSet.contains(field.getName()))
continue;
if (Modifier.isStatic(field.getModifiers()))
throw new RuntimeException(field + " cannot static on createRestWebSocketServlet");
if (Modifier.isFinal(field.getModifiers()))
throw new RuntimeException(field + " cannot final on createRestWebSocketServlet");
if (!Modifier.isPublic(field.getModifiers()) && !Modifier.isProtected(field.getModifiers())) {
throw new RuntimeException(field + " must be public or protected on createRestWebSocketServlet");
}
resourcesFieldNameSet.add(field.getName());
resourcesFieldSet.add(field);
}
} while ((clzz = clzz.getSuperclass()) != Object.class);
final List<Field> resourcesFields = new ArrayList<>(resourcesFieldSet);
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < resourcesFields.size(); i++) {
Field field = resourcesFields.get(i);
sb1.append(Type.getDescriptor(field.getType()));
sb2.append(Utility.getTypeDescriptor(field.getGenericType()));
}
final String resourceDescriptor = sb1.toString();
final String resourceGenericDescriptor = sb1.length() == sb2.length() ? null : sb2.toString();
// ----------------------------------------------------------------------------------------
final Map<String, List<String>> asmParamMap = MethodParamClassVisitor.getMethodParamNames(new HashMap<>(), webSocketType);
final Set<String> messageNames = new HashSet<>();
final List<Method> messageMethods = new ArrayList<>();
for (Method method : webSocketType.getMethods()) {
RestOnMessage rom = method.getAnnotation(RestOnMessage.class);
if (rom == null)
continue;
String name = rom.name();
if (Modifier.isFinal(method.getModifiers()))
throw new RuntimeException("@RestOnMessage method can not final but (" + method + ")");
if (Modifier.isStatic(method.getModifiers()))
throw new RuntimeException("@RestOnMessage method can not static but (" + method + ")");
if (method.getReturnType() != void.class)
throw new RuntimeException("@RestOnMessage method must return void but (" + method + ")");
if (method.getExceptionTypes().length > 0)
throw new RuntimeException("@RestOnMessage method can not throw exception but (" + method + ")");
if (name.isEmpty())
throw new RuntimeException(method + " RestOnMessage.name is empty createRestWebSocketServlet");
if (messageNames.contains(name))
throw new RuntimeException(method + " repeat RestOnMessage.name(" + name + ") createRestWebSocketServlet");
messageNames.add(name);
messageMethods.add(method);
}
// ----------------------------------------------------------------------------------------
final String resDesc = Type.getDescriptor(Resource.class);
final String wsDesc = Type.getDescriptor(WebSocket.class);
final String wsParamDesc = Type.getDescriptor(WebSocketParam.class);
final String jsonConvertDesc = Type.getDescriptor(JsonConvert.class);
final String convertDisabledDesc = Type.getDescriptor(ConvertDisabled.class);
final String webSocketParamName = Type.getInternalName(WebSocketParam.class);
final String supDynName = WebSocketServlet.class.getName().replace('.', '/');
final String webServletDesc = Type.getDescriptor(WebServlet.class);
final String webSocketInternalName = Type.getInternalName(webSocketType);
final String newDynName = webSocketInternalName.substring(0, webSocketInternalName.lastIndexOf('/') + 1) + "_Dyn" + webSocketType.getSimpleName() + "Servlet";
final String newDynWebSokcetSimpleName = "_Dyn" + webSocketType.getSimpleName();
final String newDynWebSokcetFullName = newDynName + "$" + newDynWebSokcetSimpleName;
final String newDynMessageSimpleName = "_Dyn" + webSocketType.getSimpleName() + "Message";
final String newDynMessageFullName = newDynName + "$" + newDynMessageSimpleName;
final String newDynConsumerSimpleName = "_DynRestOnMessageConsumer";
final String newDynConsumerFullName = newDynName + "$" + newDynConsumerSimpleName;
// ----------------------------------------------------------------------------------------
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
FieldVisitor fv;
MethodDebugVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null);
{
// RestDynSourceType
av0 = cw.visitAnnotation(Type.getDescriptor(RestDynSourceType.class), true);
av0.visit("value", Type.getType(Type.getDescriptor(webSocketType)));
av0.visitEnd();
}
{
// 注入 @WebServlet 注解
String urlpath = (rws.catalog().isEmpty() ? "/" : ("/" + rws.catalog() + "/")) + rwsname;
av0 = cw.visitAnnotation(webServletDesc, true);
{
AnnotationVisitor av1 = av0.visitArray("value");
av1.visit(null, urlpath);
av1.visitEnd();
}
av0.visit("moduleid", 0);
av0.visit("repair", rws.repair());
av0.visit("comment", rws.comment());
av0.visitEnd();
}
{
// 内部类
cw.visitInnerClass(newDynConsumerFullName, newDynName, newDynConsumerSimpleName, ACC_PUBLIC + ACC_STATIC);
cw.visitInnerClass(newDynWebSokcetFullName, newDynName, newDynWebSokcetSimpleName, ACC_PUBLIC + ACC_STATIC);
cw.visitInnerClass(newDynMessageFullName, newDynName, newDynMessageSimpleName, ACC_PUBLIC + ACC_STATIC);
for (int i = 0; i < messageMethods.size(); i++) {
Method method = messageMethods.get(i);
String endfix = "_" + method.getName() + "_" + (i > 9 ? i : ("0" + i));
cw.visitInnerClass(newDynMessageFullName + endfix, newDynName, newDynMessageSimpleName + endfix, ACC_PUBLIC + ACC_STATIC);
}
}
{
// @Resource
for (int i = 0; i < resourcesFields.size(); i++) {
Field field = resourcesFields.get(i);
Resource res = field.getAnnotation(Resource.class);
java.lang.reflect.Type fieldType = field.getGenericType();
fv = cw.visitField(ACC_PRIVATE, "_redkale_resource_" + i, Type.getDescriptor(field.getType()), fieldType == field.getType() ? null : Utility.getTypeDescriptor(fieldType), null);
{
av0 = fv.visitAnnotation(resDesc, true);
av0.visit("name", res.name());
av0.visitEnd();
}
fv.visitEnd();
}
}
{
// _DynWebSocketServlet构造函数
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "()V", false);
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(Type.getObjectType(newDynName + "$" + newDynWebSokcetSimpleName + "Message"));
mv.visitFieldInsn(PUTFIELD, newDynName, "messageTextType", "Ljava/lang/reflect/Type;");
mv.visitVarInsn(ALOAD, 0);
pushInt(mv, rws.liveinterval());
mv.visitFieldInsn(PUTFIELD, newDynName, "liveinterval", "I");
mv.visitVarInsn(ALOAD, 0);
pushInt(mv, rws.wsmaxconns());
mv.visitFieldInsn(PUTFIELD, newDynName, "wsmaxconns", "I");
mv.visitVarInsn(ALOAD, 0);
pushInt(mv, rws.wsmaxbody());
mv.visitFieldInsn(PUTFIELD, newDynName, "wsmaxbody", "I");
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(rws.single() ? ICONST_1 : ICONST_0);
mv.visitFieldInsn(PUTFIELD, newDynName, "single", "Z");
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(rws.anyuser() ? ICONST_1 : ICONST_0);
mv.visitFieldInsn(PUTFIELD, newDynName, "anyuser", "Z");
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
{
// createWebSocket 方法
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PROTECTED, "createWebSocket", "()" + wsDesc, "<G::Ljava/io/Serializable;T:Ljava/lang/Object;>()L" + WebSocket.class.getName().replace('.', '/') + "<TG;TT;>;", null));
mv.visitTypeInsn(NEW, newDynName + "$" + newDynWebSokcetSimpleName);
mv.visitInsn(DUP);
for (int i = 0; i < resourcesFields.size(); i++) {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "_redkale_resource_" + i, Type.getDescriptor(resourcesFields.get(i).getType()));
}
mv.visitMethodInsn(INVOKESPECIAL, newDynWebSokcetFullName, "<init>", "(" + resourceDescriptor + ")V", false);
mv.visitInsn(ARETURN);
mv.visitMaxs(2 + resourcesFields.size(), 1);
mv.visitEnd();
}
{
// createRestOnMessageConsumer
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PROTECTED, "createRestOnMessageConsumer", "()Ljava/util/function/BiConsumer;", "()Ljava/util/function/BiConsumer<" + wsDesc + "Ljava/lang/Object;>;", null));
mv.visitTypeInsn(NEW, newDynConsumerFullName);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, newDynConsumerFullName, "<init>", "()V", false);
mv.visitInsn(ARETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
{
// resourceName
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "resourceName", "()Ljava/lang/String;", null, null));
mv.visitLdcInsn(rwsname);
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
RestClassLoader newLoader = new RestClassLoader(loader);
for (int i = 0; i < messageMethods.size(); i++) {
// _DyncXXXWebSocketMessage 子消息List
Method method = messageMethods.get(i);
String endfix = "_" + method.getName() + "_" + (i > 9 ? i : ("0" + i));
ClassWriter cw2 = new ClassWriter(COMPUTE_FRAMES);
cw2.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynMessageFullName + endfix, null, "java/lang/Object", new String[] { webSocketParamName, "java/lang/Runnable" });
cw2.visitInnerClass(newDynMessageFullName + endfix, newDynName, newDynMessageSimpleName + endfix, ACC_PUBLIC + ACC_STATIC);
Set<String> paramnames = new HashSet<>();
String methodesc = method.getName() + ":" + Type.getMethodDescriptor(method);
List<String> names = asmParamMap.get(methodesc);
Parameter[] params = method.getParameters();
// 必须使用LinkedHashMap确保顺序
final LinkedHashMap<String, Parameter> paramap = new LinkedHashMap();
for (int j = 0; j < params.length; j++) {
// 字段列表
Parameter param = params[j];
String paramname = param.getName();
RestParam rp = param.getAnnotation(RestParam.class);
if (rp != null && !rp.name().isEmpty()) {
paramname = rp.name();
} else if (names != null && names.size() > j) {
paramname = names.get(j);
}
if (paramnames.contains(paramname))
throw new RuntimeException(method + " has same @RestParam.name");
paramnames.add(paramname);
paramap.put(paramname, param);
fv = cw2.visitField(ACC_PUBLIC, paramname, Type.getDescriptor(param.getType()), param.getType() == param.getParameterizedType() ? null : Utility.getTypeDescriptor(param.getParameterizedType()), null);
fv.visitEnd();
}
{
// _redkale_websocket
fv = cw2.visitField(ACC_PUBLIC, "_redkale_websocket", "L" + newDynWebSokcetFullName + ";", null, null);
av0 = fv.visitAnnotation(convertDisabledDesc, true);
av0.visitEnd();
fv.visitEnd();
}
{
// 空构造函数
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
// getNames
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "getNames", "()[Ljava/lang/String;", null, null));
pushInt(mv, paramap.size());
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
int index = -1;
for (Map.Entry<String, Parameter> en : paramap.entrySet()) {
mv.visitInsn(DUP);
pushInt(mv, ++index);
mv.visitLdcInsn(en.getKey());
mv.visitInsn(AASTORE);
}
mv.visitInsn(ARETURN);
mv.visitMaxs(paramap.size() + 2, 1);
mv.visitEnd();
}
{
// getValue
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "getValue", "(Ljava/lang/String;)Ljava/lang/Object;", "<T:Ljava/lang/Object;>(Ljava/lang/String;)TT;", null));
for (Map.Entry<String, Parameter> en : paramap.entrySet()) {
Class paramType = en.getValue().getType();
mv.visitLdcInsn(en.getKey());
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
Label l1 = new Label();
mv.visitJumpInsn(IFEQ, l1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynMessageFullName + endfix, en.getKey(), Type.getDescriptor(paramType));
if (paramType.isPrimitive()) {
Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(paramType, 1), 0).getClass();
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(paramType) + ")" + Type.getDescriptor(bigclaz), false);
}
mv.visitInsn(ARETURN);
mv.visitLabel(l1);
}
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
// execute
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "execute", "(L" + newDynWebSokcetFullName + ";)V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, newDynMessageFullName + endfix, "_redkale_websocket", "L" + newDynWebSokcetFullName + ";");
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(method.getAnnotation(RestOnMessage.class).name());
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, newDynWebSokcetFullName, "preOnMessage", "(Ljava/lang/String;" + wsParamDesc + "Ljava/lang/Runnable;)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(4, 2);
mv.visitEnd();
}
{
// run
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "run", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynMessageFullName + endfix, "_redkale_websocket", "L" + newDynWebSokcetFullName + ";");
for (Map.Entry<String, Parameter> en : paramap.entrySet()) {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, (newDynMessageFullName + endfix), en.getKey(), Type.getDescriptor(en.getValue().getType()));
}
mv.visitMethodInsn(INVOKEVIRTUAL, newDynWebSokcetFullName, method.getName(), Type.getMethodDescriptor(method), false);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
{
// toString
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null));
mv.visitMethodInsn(INVOKESTATIC, JsonConvert.class.getName().replace('.', '/'), "root", "()" + jsonConvertDesc, false);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, JsonConvert.class.getName().replace('.', '/'), "convertTo", "(Ljava/lang/Object;)Ljava/lang/String;", false);
mv.visitInsn(ARETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
cw2.visitEnd();
newLoader.loadClass((newDynMessageFullName + endfix).replace('/', '.'), cw2.toByteArray());
}
{
// _DynXXXWebSocketMessage class
ClassWriter cw2 = new ClassWriter(COMPUTE_FRAMES);
cw2.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynMessageFullName, null, "java/lang/Object", null);
cw2.visitInnerClass(newDynMessageFullName, newDynName, newDynMessageSimpleName, ACC_PUBLIC + ACC_STATIC);
for (int i = 0; i < messageMethods.size(); i++) {
Method method = messageMethods.get(i);
String endfix = "_" + method.getName() + "_" + (i > 9 ? i : ("0" + i));
cw2.visitInnerClass(newDynMessageFullName + endfix, newDynName, newDynMessageSimpleName + endfix, ACC_PUBLIC + ACC_STATIC);
fv = cw2.visitField(ACC_PUBLIC, method.getAnnotation(RestOnMessage.class).name(), "L" + newDynMessageFullName + endfix + ";", null, null);
fv.visitEnd();
}
{
// 构造函数
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
// toString
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null));
mv.visitMethodInsn(INVOKESTATIC, JsonConvert.class.getName().replace('.', '/'), "root", "()" + jsonConvertDesc, false);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, JsonConvert.class.getName().replace('.', '/'), "convertTo", "(Ljava/lang/Object;)Ljava/lang/String;", false);
mv.visitInsn(ARETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
cw2.visitEnd();
newLoader.loadClass(newDynMessageFullName.replace('/', '.'), cw2.toByteArray());
}
{
// _DynXXXWebSocket class
ClassWriter cw2 = new ClassWriter(COMPUTE_FRAMES);
cw2.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynWebSokcetFullName, null, webSocketInternalName, null);
cw2.visitInnerClass(newDynWebSokcetFullName, newDynName, newDynWebSokcetSimpleName, ACC_PUBLIC + ACC_STATIC);
{
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "<init>", "(" + resourceDescriptor + ")V", resourceGenericDescriptor == null ? null : ("(" + resourceGenericDescriptor + ")V"), null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, webSocketInternalName, "<init>", "()V", false);
for (int i = 0; i < resourcesFields.size(); i++) {
Field field = resourcesFields.get(i);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, i + 1);
mv.visitFieldInsn(PUTFIELD, newDynWebSokcetFullName, field.getName(), Type.getDescriptor(field.getType()));
}
mv.visitInsn(RETURN);
mv.visitMaxs(2, 1 + resourcesFields.size());
mv.visitEnd();
}
cw2.visitEnd();
newLoader.loadClass(newDynWebSokcetFullName.replace('/', '.'), cw2.toByteArray());
}
{
// _DynRestOnMessageConsumer class
ClassWriter cw2 = new ClassWriter(COMPUTE_FRAMES);
cw2.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynConsumerFullName, "Ljava/lang/Object;Ljava/util/function/BiConsumer<" + wsDesc + "Ljava/lang/Object;>;", "java/lang/Object", new String[] { "java/util/function/BiConsumer" });
cw2.visitInnerClass(newDynConsumerFullName, newDynName, newDynConsumerSimpleName, ACC_PUBLIC + ACC_STATIC);
cw2.visitInnerClass(newDynMessageFullName, newDynName, newDynMessageSimpleName, ACC_PUBLIC + ACC_STATIC);
for (int i = 0; i < messageMethods.size(); i++) {
Method method = messageMethods.get(i);
String endfix = "_" + method.getName() + "_" + (i > 9 ? i : ("0" + i));
cw2.visitInnerClass(newDynMessageFullName + endfix, newDynName, newDynMessageSimpleName + endfix, ACC_PUBLIC + ACC_STATIC);
}
{
// 构造函数
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
// accept函数
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC, "accept", "(" + wsDesc + "Ljava/lang/Object;)V", null, null));
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, newDynWebSokcetFullName);
mv.visitVarInsn(ASTORE, 3);
mv.visitVarInsn(ALOAD, 2);
mv.visitTypeInsn(CHECKCAST, newDynMessageFullName);
mv.visitVarInsn(ASTORE, 4);
for (int i = 0; i < messageMethods.size(); i++) {
final Method method = messageMethods.get(i);
String endfix = "_" + method.getName() + "_" + (i > 9 ? i : ("0" + i));
final String messagename = method.getAnnotation(RestOnMessage.class).name();
mv.visitVarInsn(ALOAD, 4);
mv.visitFieldInsn(GETFIELD, newDynMessageFullName, messagename, "L" + (newDynMessageFullName + endfix) + ";");
Label ifLabel = new Label();
mv.visitJumpInsn(IFNULL, ifLabel);
mv.visitVarInsn(ALOAD, 4);
mv.visitFieldInsn(GETFIELD, newDynMessageFullName, messagename, "L" + (newDynMessageFullName + endfix) + ";");
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn(INVOKEVIRTUAL, (newDynMessageFullName + endfix), "execute", "(L" + newDynWebSokcetFullName + ";)V", false);
mv.visitInsn(RETURN);
mv.visitLabel(ifLabel);
}
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3 + messageMethods.size());
mv.visitEnd();
}
{
// 虚拟accept函数
mv = new MethodDebugVisitor(cw2.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "accept", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null));
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitTypeInsn(CHECKCAST, WebSocket.class.getName().replace('.', '/'));
mv.visitVarInsn(ALOAD, 2);
mv.visitTypeInsn(CHECKCAST, "java/lang/Object");
mv.visitMethodInsn(INVOKEVIRTUAL, newDynConsumerFullName, "accept", "(" + wsDesc + "Ljava/lang/Object;)V", false);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
mv.visitEnd();
}
cw2.visitEnd();
newLoader.loadClass(newDynConsumerFullName.replace('/', '.'), cw2.toByteArray());
}
cw.visitEnd();
Class<?> newClazz = newLoader.loadClass(newDynName.replace('/', '.'), cw.toByteArray());
try {
return (T) newClazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Aggregations