Search in sources :

Example 1 with Resource

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);
        }
    }
}
Also used : Resource(javax.annotation.Resource) NamingException(javax.naming.NamingException)

Example 2 with Resource

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);
            }
        }
    }
}
Also used : InjectionCollection(org.eclipse.jetty.plus.annotation.InjectionCollection) NameNotFoundException(javax.naming.NameNotFoundException) MetaData(org.eclipse.jetty.webapp.MetaData) Resource(javax.annotation.Resource) NamingException(javax.naming.NamingException) Injection(org.eclipse.jetty.plus.annotation.Injection) InitialContext(javax.naming.InitialContext)

Example 3 with Resource

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);
}
Also used : PropertyDescriptor(java.beans.PropertyDescriptor) Resource(javax.annotation.Resource) Method(java.lang.reflect.Method) LinkedList(java.util.LinkedList) Field(java.lang.reflect.Field) InjectionMetadata(org.springframework.beans.factory.annotation.InjectionMetadata) ReflectionUtils(org.springframework.util.ReflectionUtils)

Example 4 with Resource

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());
            }
        }
    }
}
Also used : Inject(javax.inject.Inject) Field(java.lang.reflect.Field) Autowired(org.springframework.beans.factory.annotation.Autowired) Resource(javax.annotation.Resource)

Example 5 with Resource

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);
    }
}
Also used : MethodDebugVisitor(org.redkale.asm.MethodDebugVisitor) Resource(javax.annotation.Resource) Type(org.redkale.asm.Type) ElementType(java.lang.annotation.ElementType)

Aggregations

Resource (javax.annotation.Resource)59 Collectors (java.util.stream.Collectors)22 Set (java.util.Set)20 List (java.util.List)18 Subject (alien4cloud.security.Subject)17 Sets (com.google.common.collect.Sets)17 Arrays (java.util.Arrays)17 ArrayUtils (org.apache.commons.lang3.ArrayUtils)15 IGenericSearchDAO (alien4cloud.dao.IGenericSearchDAO)14 ApplicationEnvironmentService (alien4cloud.application.ApplicationEnvironmentService)12 ApplicationEnvironment (alien4cloud.model.application.ApplicationEnvironment)12 Audit (alien4cloud.audit.annotation.Audit)11 ResourcePermissionService (alien4cloud.authorization.ResourcePermissionService)11 RestResponse (alien4cloud.rest.model.RestResponse)11 RestResponseBuilder (alien4cloud.rest.model.RestResponseBuilder)11 ApplicationEnvironmentAuthorizationUpdateRequest (alien4cloud.rest.orchestrator.model.ApplicationEnvironmentAuthorizationUpdateRequest)11 ApiOperation (io.swagger.annotations.ApiOperation)11 IOException (java.io.IOException)11 MediaType (org.springframework.http.MediaType)11 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)11