Package cn.agrael.struts.plugin.ejb3

Source Code of cn.agrael.struts.plugin.ejb3.StrutsEJBUtils

package cn.agrael.struts.plugin.ejb3;

import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.ACTION_PROXY_INTERFACES;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.ENC_PATH;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.INTERCEPTOR_INTERFACES;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.IS_PARSE_EJB_ANNOTATION;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.IS_PARSE_RESOURCE_ANNOTATION;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.LOCAL;
import static cn.agrael.struts.plugin.ejb3.StrutsEJBPluginConstant.REMOTE;
import static com.opensymphony.xwork2.inject.util.ReferenceType.SOFT;
import static com.opensymphony.xwork2.inject.util.ReferenceType.STRONG;
import static com.opensymphony.xwork2.inject.util.ReferenceType.WEAK;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.interceptor.AroundInvoke;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.ExcludeDefaultInterceptors;
import javax.interceptor.Interceptors;
import javax.interceptor.InvocationContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import cn.agrael.struts.plugin.ejb3.annotation.EJBComponent;
import cn.agrael.struts.plugin.ejb3.annotation.ResourceComponent;
import cn.agrael.util.ObjectUtils;

import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.inject.util.ReferenceMap;
import com.opensymphony.xwork2.interceptor.Interceptor;

/**
* struts 与 EJB 整合的相关工具。
*
* @author <a href="mailto:agraellee@gmail.com">Agrael·Lee</a>
*
*/
public class StrutsEJBUtils {

  /** 以完全类名为 key 的 BeanEJBAnnotation 缓存 */
  private static final ReferenceMap<String, BeanEJBAnnotation> BEAN_EJB_ANNOTATION_CACHE = new ReferenceMap<String, BeanEJBAnnotation>(
      STRONG, SOFT);

  /** 以完全类名为 key 的 Action公开方法 缓存 */
  private static final ReferenceMap<Class<?>, Set<String>> ACTION_PUBLIC_METHODS_CACHE = new ReferenceMap<Class<?>, Set<String>>(WEAK,
      STRONG);

  private StrutsEJBUtils() {
  }

  /**
   * 得到一个类缓存中的 BeanEJBAnnotation。
   *
   * @param beanName 完全类名。
   * @return beanName 在 缓存中的 BeanEJBAnnotation ,如果不存在则返回 null。
   */
  public static BeanEJBAnnotation getBeanEJBAnnotation(String beanName) {
    return BEAN_EJB_ANNOTATION_CACHE.get(beanName);
  }

  /**
   * 得到 bean 实例的类在缓存中的 BeanEJBAnnotation。
   *
   * @param bean 要得到缓存中的 BeanEJBAnnotation 的bean实例。
   * @return bean 实例的类 缓存中的 BeanEJBAnnotation ,如果不存在则返回 null。
   * @see #getBeanEJBAnnotation(String)
   */
  public static BeanEJBAnnotation getBeanEJBAnnotation(Object bean) {
    if (bean == null) {
      return null;
    }
    return getBeanEJBAnnotation(bean.getClass().getName());
  }

  /**
   * 查看缓存中是否存在 beanName 对应的BeanEJBAnnotation。
   *
   * @param beanName 完全类名。
   * @return 存在返回 true ,不存在返回 false。
   */
  public static boolean hasBeanEJBAnnotation(String beanName) {
    return BEAN_EJB_ANNOTATION_CACHE.containsKey(beanName);
  }

  /**
   * 查看缓存中是否存在 bean 实例的类 对应的BeanEJBAnnotation。
   *
   * @param bean 要得查看缓存中是否存在 BeanEJBAnnotation 的bean实例。
   * @return 存在返回 true ,不存在返回 false。
   */
  public static boolean hasBeanEJBAnnotation(Object bean) {
    if (bean == null) {
      return false;
    }
    return hasBeanEJBAnnotation(bean.getClass().getName());
  }

  /**
   * 解析 bean 的 EJB 注解并返回 bean 的 EJB 注解信息。
   *
   * @param bean 需要解析注解的对象。
   * @return bean 的 EJB 注解信息。
   * @throws Exception 发生任何异常时。
   */
  public static BeanEJBAnnotation parseBeanEJBAnnotation(Object bean) throws Exception {
    if (bean == null) {
      return null;
    }
    Class<?> clazz = bean.getClass();
    String className = clazz.getName();
    BeanEJBAnnotation beanEJBAnnotation = BEAN_EJB_ANNOTATION_CACHE.get(className);
    if (beanEJBAnnotation == null) {
      synchronized (BEAN_EJB_ANNOTATION_CACHE) {
        if ((beanEJBAnnotation = BEAN_EJB_ANNOTATION_CACHE.get(className)) == null) {
          beanEJBAnnotation = new BeanEJBAnnotation();
          // 类注解
          boolean isKeep = false;
          for (Annotation annotation : clazz.getAnnotations()) {
            if (!isKeep && annotation instanceof Resource) {
              beanEJBAnnotation.setClassInject(new ClassInjectAnnotationWrapper(annotation));
              isKeep = true;
            }
            if (!isKeep && annotation instanceof EJB) {
              beanEJBAnnotation.setClassInject(new ClassInjectAnnotationWrapper(annotation));
              isKeep = true;
            }
            if (!isKeep && annotation.getClass().isAnnotationPresent(ResourceComponent.class)) {
              beanEJBAnnotation.setClassInject(new ClassInjectAnnotationWrapper(annotation));
              isKeep = true;
            }
            if (!isKeep && annotation.getClass().isAnnotationPresent(EJBComponent.class)) {
              beanEJBAnnotation.setClassInject(new ClassInjectAnnotationWrapper(annotation));
              isKeep = true;
            }
            if (annotation instanceof Interceptors) {
              InterceptorsAnnotationWrapper interceptorsAnnotationWrapper = new InterceptorsAnnotationWrapper();
              Interceptors interceptorsAnnotation = (Interceptors) annotation;
              Class<?>[] interceptorClasses = interceptorsAnnotation.value();
              InterceptorsAnnotationEntry[] interceptors = new InterceptorsAnnotationEntry[interceptorClasses.length];
              for (int i = 0; i < interceptors.length; i++) {
                interceptors[i] = new InterceptorsAnnotationEntry(ObjectUtils.createObject(interceptorClasses[i]),
                    findInterceptorMethod(interceptorClasses[i]));
              }
              interceptorsAnnotationWrapper.setInterceptors(interceptors);
              if (clazz.isAnnotationPresent(ExcludeDefaultInterceptors.class)) {
                // 排除默认拦截
                interceptorsAnnotationWrapper.setExcludeDefaultInterceptors(true);
              }
              beanEJBAnnotation.setClassInterceptors(interceptorsAnnotationWrapper);
            }
          }
          // 字段注解
          Field[] fields = ObjectUtils.getAllField(clazz);
          for (Field field : fields) {
            for (Annotation annotation : field.getAnnotations()) {
              if (annotation instanceof Resource) {
                beanEJBAnnotation.addFieldInject(field.getName(), new FieldInjectAnnotationWrapper(field, annotation));
                break;
              }
              if (annotation instanceof EJB) {
                beanEJBAnnotation.addFieldInject(field.getName(), new FieldInjectAnnotationWrapper(field, annotation));
                break;
              }
              if (annotation.getClass().isAnnotationPresent(ResourceComponent.class)) {
                beanEJBAnnotation.addFieldInject(field.getName(), new FieldInjectAnnotationWrapper(field, annotation));
                break;
              }
              if (annotation.getClass().isAnnotationPresent(EJBComponent.class)) {
                beanEJBAnnotation.addFieldInject(field.getName(), new FieldInjectAnnotationWrapper(field, annotation));
                break;
              }
            }
          }
          // 方法注解
          Method[] methods = clazz.getMethods();
          for (Method method : methods) {
            String methodName = method.getName();
            isKeep = false;
            for (Annotation annotation : method.getAnnotations()) {
              if (!isKeep && annotation instanceof Resource) {
                beanEJBAnnotation.addMethodInject(methodName, new MethodInjectAnnotationWrapper(method, annotation));
                isKeep = true;
              }
              if (!isKeep && annotation instanceof EJB) {
                beanEJBAnnotation.addMethodInject(methodName, new MethodInjectAnnotationWrapper(method, annotation));
                isKeep = true;
              }
              if (!isKeep && annotation.getClass().isAnnotationPresent(ResourceComponent.class)) {
                beanEJBAnnotation.addMethodInject(methodName, new MethodInjectAnnotationWrapper(method, annotation));
                isKeep = true;
              }
              if (!isKeep && annotation.getClass().isAnnotationPresent(EJBComponent.class)) {
                beanEJBAnnotation.addMethodInject(methodName, new MethodInjectAnnotationWrapper(method, annotation));
                isKeep = true;
              }
              if (annotation instanceof Interceptors) {
                InterceptorsAnnotationWrapper interceptorsAnnotationWrapper = new InterceptorsAnnotationWrapper();
                Interceptors interceptorsAnnotation = (Interceptors) annotation;
                Class<?>[] interceptorClasses = interceptorsAnnotation.value();
                InterceptorsAnnotationEntry[] interceptors = new InterceptorsAnnotationEntry[interceptorClasses.length];
                for (int i = 0; i < interceptors.length; i++) {
                  interceptors[i] = new InterceptorsAnnotationEntry(ObjectUtils.createObject(interceptorClasses[i]),
                      findInterceptorMethod(interceptorClasses[i]));
                }
                interceptorsAnnotationWrapper.setInterceptors(interceptors);
                if (method.isAnnotationPresent(ExcludeDefaultInterceptors.class)) {
                  // 排除默认拦截
                  interceptorsAnnotationWrapper.setExcludeDefaultInterceptors(true);
                }
                if (method.isAnnotationPresent(ExcludeClassInterceptors.class)) {
                  // 排除类拦截
                  interceptorsAnnotationWrapper.setExcludeClassInterceptors(true);
                }
                beanEJBAnnotation.addMethodInterceptor(methodName, interceptorsAnnotationWrapper);
              }
              if (annotation instanceof PostConstruct) {
                // 初始化回调
                beanEJBAnnotation.setPostConstructAnnotationMethod(method);
              }
              if (annotation instanceof PreDestroy) {
                // 清除回调
                beanEJBAnnotation.setPreDestroyAnnotationMethod(method);
              }
            }
          }
          // 加入缓存
          BEAN_EJB_ANNOTATION_CACHE.put(className, beanEJBAnnotation);
        }
      }
    }
    return beanEJBAnnotation;
  }

  /**
   * 执行EJB注入注解( {@link EJB} {@link Resource})。该方法不包含 {@link Interceptors}
   * {@link PreDestroy} {@link PostConstruct}
   * 这样的生命周期方法的处理。要处理这些注解请使用工具的其他方法。
   *
   * @param bean 要执行 EJB 注入的 bean 实例。
   * @return bean 对应的 BeanEJBAnnotation 信息。
   * @throws Exception 发生任何异常。
   */
  public static BeanEJBAnnotation executeEJBInjectAnnotation(Object bean) throws Exception {
    if (bean == null) {
      return null;
    }
    BeanEJBAnnotation beanEJBAnnotation = parseBeanEJBAnnotation(bean);
    if (beanEJBAnnotation.isEmpty()) {
      return beanEJBAnnotation;
    }
    // 字段注入
    Map<String, FieldInjectAnnotationWrapper> fieldInjectAnnotationWrapper = beanEJBAnnotation.getFieldInjects();
    for (FieldInjectAnnotationWrapper injectAnnotationWrapper : fieldInjectAnnotationWrapper.values()) {
      fieldInject(bean, injectAnnotationWrapper);
    }
    // 方法注入
    Map<String, MethodInjectAnnotationWrapper> methodInjectAnnotationWrapper = beanEJBAnnotation.getMethodInjects();
    for (MethodInjectAnnotationWrapper injectAnnotationWrapper : methodInjectAnnotationWrapper.values()) {
      methodInject(bean, injectAnnotationWrapper);
    }
    return beanEJBAnnotation;
  }

  /**
   * 创建 {@link Interceptor} 代理。
   *
   * @param interceptor 需要代理的 Interceptor。
   * @param beanEJBAnnotation interceptor 的 BeanEJBAnnotation。
   * @return 如果 interceptor 为null 或者 beanEJBAnnotation 为 null 或者
   *         beanEJBAnnotation 为空,则直接返回 actionProxy ,否则返回创建的代理实例。
   */
  public static Interceptor createInterceptorsAnnotationProxy(Interceptor interceptor, BeanEJBAnnotation beanEJBAnnotation) {
    if (interceptor == null || beanEJBAnnotation == null || beanEJBAnnotation.isEmpty()) {
      return interceptor;
    }
    return (Interceptor) Proxy.newProxyInstance(
        ObjectUtils.getDefaultClassLoader(),
        INTERCEPTOR_INTERFACES,
        new InterceptorProxyHandler(interceptor, beanEJBAnnotation.getClassInterceptors(), beanEJBAnnotation
            .getMethodInterceptors()));
  }

  /**
   * 创建 {@link ActionProxy} 代理。
   *
   * @param actionProxy 需要代理的 ActionProxy。
   * @param beanEJBAnnotation actionProxy 中的 action 的 BeanEJBAnnotation。
   * @return 如果 actionProxy 为null 或者 beanEJBAnnotation 为 null 或者
   *         beanEJBAnnotation 为空,则直接返回 actionProxy ,否则返回创建的代理实例。
   */
  public static ActionProxy createActionAnnotationProxy(ActionProxy actionProxy, BeanEJBAnnotation beanEJBAnnotation) {
    if (actionProxy == null || beanEJBAnnotation == null || beanEJBAnnotation.isEmpty()) {
      return actionProxy;
    }
    return (ActionProxy) Proxy.newProxyInstance(ObjectUtils.getDefaultClassLoader(), ACTION_PROXY_INTERFACES, new ActionProxyHandler(
        actionProxy, beanEJBAnnotation.getClassInterceptors(), beanEJBAnnotation.getMethodInterceptors()));
  }

  /**
   * 创建 拦截器回调方法的上下文信息。
   *
   * @param target 目标实例。
   * @param method 调用 Interceptor 的 Bean 类的方法。
   * @param args 包含传入代理实例上方法调用的参数值的对象数组。
   * @param methodInterceptorsAnnotationWrapper 当前目标实例与方法的方法级别拦截器注解信息包装器。
   * @param classInterceptorsAnnotationWrapper 当前目标实例与方法的类级别拦截器注解信息包装器。
   * @return 对应信息的 拦截器回调方法的上下文信息。
   * @throws NullPointerException 拦截器包装器中的参数为 null 时。
   */
  public static InvocationContext createInvocationContext(Object target, Method method, Object[] args,
      InterceptorsAnnotationWrapper methodInterceptorsAnnotationWrapper,
      InterceptorsAnnotationWrapper classInterceptorsAnnotationWrapper) {
    List<InterceptorsAnnotationEntry> interceptors = new ArrayList<InterceptorsAnnotationEntry>(
        classInterceptorsAnnotationWrapper.getInterceptors().length);
    if (methodInterceptorsAnnotationWrapper == null) {
      if (classInterceptorsAnnotationWrapper != null) {
        // 如果没有方法级别拦截器则直接添加类级别拦截器
        Collections.addAll(interceptors, classInterceptorsAnnotationWrapper.getInterceptors());
      }
    } else {
      if (classInterceptorsAnnotationWrapper != null && !methodInterceptorsAnnotationWrapper.isExcludeClassInterceptors()) {
        // 没有排除类级别拦截器则添加上类级别拦截器
        Collections.addAll(interceptors, classInterceptorsAnnotationWrapper.getInterceptors());
      }
      // 添加方法拦截器
      Collections.addAll(interceptors, methodInterceptorsAnnotationWrapper.getInterceptors());
    }
    return new InvocationContextImpl(target, method, interceptors.iterator());
  }

  /**
   * 字段注解注入。
   *
   * @param bean 需要注入的 bean 实例。
   * @param fieldInjectAnnotationWrapper 字段级别注入注解包装器。
   * @throws Exception 发生任何异常。
   */
  public static void fieldInject(Object bean, FieldInjectAnnotationWrapper fieldInjectAnnotationWrapper) throws Exception {
    if (bean == null) {
      return;
    }
    Object resourceObject = null;
    String jndiPath = fieldInjectAnnotationWrapper.getJndiPath();
    Field field = fieldInjectAnnotationWrapper.getField();
    if (jndiPath == null) {
      Annotation annotation = fieldInjectAnnotationWrapper.getInjectAnnotation();
      if ("true".equals(IS_PARSE_RESOURCE_ANNOTATION) && annotation instanceof Resource) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.fieldResourceAnnotationLookup(bean.getClass(),
            fieldInjectAnnotationWrapper);
      } else if ("true".equals(IS_PARSE_EJB_ANNOTATION) && annotation instanceof EJB) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.fieldEJBAnnotationLookup(bean.getClass(),
            fieldInjectAnnotationWrapper);
      } else if (annotation.getClass().isAnnotationPresent(ResourceComponent.class)) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.fieldResourceComponentAnnotationLookup(bean.getClass(),
            fieldInjectAnnotationWrapper);
      } else if (annotation.getClass().isAnnotationPresent(EJBComponent.class)) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.fieldEJBComponentAnnotationLookup(bean.getClass(),
            fieldInjectAnnotationWrapper);
      }
    } else {
      resourceObject = lookup(jndiPath);
    }
    // 注入
    fieldInject(bean, field, resourceObject);
  }

  /**
   * 查找 clazz 上是 Local 或者 Remote 注解,并返回配置中 Local/Remote 对应的字符串。
   *
   * @param clazz 要查找的 Class。
   * @return 如果找到 Local/Remote注解 ,则返回配置中 Local/Remote 对应的字符串,如果没有,则返回 null。
   */
  public static String findLocalOrRemote(Class<?> clazz) {
    // 找寻类注解上的本地/远程注解
    if (clazz.isAnnotationPresent(Local.class)) {
      // 本地接口
      return LOCAL;
    } else if (clazz.isAnnotationPresent(Remote.class)) {
      // 远程接口
      return REMOTE;
    } else {
      // 都不是
      return null;
    }
  }

  private static void fieldInject(Object object, final Field field, Object resourceObject) throws Exception {
    // 注入
    ObjectUtils.fieldSetAccessible(field);
    field.set(object, resourceObject);
  }

  /**
   * 方法注解注入。
   *
   * @param bean 需要注入的 bean 实例。
   * @param methodInjectAnnotationWrapper 方法级别注入注解包装器。
   * @throws Exception 发生任何异常。
   */
  public static void methodInject(Object bean, MethodInjectAnnotationWrapper methodInjectAnnotationWrapper) throws Exception {
    if (bean == null) {
      return;
    }
    Object resourceObject = null;
    String jndiPath = methodInjectAnnotationWrapper.getJndiPath();
    Method method = methodInjectAnnotationWrapper.getMethod();
    if (jndiPath == null) {
      Annotation annotation = methodInjectAnnotationWrapper.getInjectAnnotation();
      if ("true".equals(IS_PARSE_RESOURCE_ANNOTATION) && annotation instanceof Resource) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.methodResourceAnnotationLookup(bean.getClass(),
            methodInjectAnnotationWrapper);
      } else if ("true".equals(IS_PARSE_EJB_ANNOTATION) && annotation instanceof EJB) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.methodEJBAnnotationLookup(bean.getClass(),
            methodInjectAnnotationWrapper);
      } else if (annotation.getClass().isAnnotationPresent(ResourceComponent.class)) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.methodResourceComponentAnnotationLookup(bean.getClass(),
            methodInjectAnnotationWrapper);
      } else if (annotation.getClass().isAnnotationPresent(EJBComponent.class)) {
        resourceObject = StrutsEJBPluginConstant.EJB_CONTAINER.methodEJBComponentAnnotationLookup(bean.getClass(),
            methodInjectAnnotationWrapper);
      }
    } else {
      resourceObject = lookup(jndiPath);
    }
    // 注入
    methodInject(bean, method, resourceObject);
  }

  private static void methodInject(Object object, final Method method, Object resourceObject) throws Exception {
    // 注入
    ObjectUtils.methodSetAccessible(method);
    method.invoke(object, resourceObject);
  }

  /**
   * 查找资源。
   *
   * @param name 资源的jndi名。
   * @return name 对应的资源。
   * @throws NamingException 如果遇到命名异常。
   */
  public static Object lookup(String name) throws NamingException {
    Context context = new InitialContext();
    try {
      return context.lookup(name);
    } finally {
      if (context != null) {
        context.close();
      }
    }
  }

  /**
   * 从ENC上下文开始查找。
   *
   * @param name 相对于 ENC 的资源 jndi 名。
   * @return 相对于 ENC 的name 对应的资源。
   * @throws NamingException 如果遇到命名异常。
   */
  public static Object lookupENC(String name) throws NamingException {
    return lookup(ENC_PATH + name);
  }

  /**
   * 从一个 Class 中找标注有 {@link AroundInvoke} 的方法。
   *
   * @param interceptorClass 要寻找的 Class 实例。
   * @return 返回 {@link AroundInvoke} 标注的方法,如过有多个则返回查找到的第一个,如果 interceptorClass
   *         为 null 则返回 null。
   * @throws NoSuchMethodException 如果没有找到拦截方法。
   */
  public static Method findInterceptorMethod(Class<?> interceptorClass) throws NoSuchMethodException {
    if (interceptorClass == null) {
      return null;
    }
    Method[] methods = interceptorClass.getDeclaredMethods();
    for (Method method : methods) {
      if (method.isAnnotationPresent(AroundInvoke.class)) {
        return method;
      }
    }
    throw new NoSuchMethodException("拦截器 [" + interceptorClass.getName() + "] 没有找到拦截方法。");
  }

  /**
   * 模拟Bean生命周期。
   *
   * @param bean 需要模拟生命周期的 bean 实例。
   * @param beanEJBAnnotation bean 对应的 BeanEJBAnnotation。
   * @throws Exception 发生任何异常时。
   */
  public static void simulation(Object bean, BeanEJBAnnotation beanEJBAnnotation) throws Exception {
    // 初始化回调
    Method postConstructMethod = beanEJBAnnotation.getPostConstructAnnotationMethod();
    Map<String, InterceptorsAnnotationWrapper> methodInterceptors = beanEJBAnnotation.getMethodInterceptors();
    if (postConstructMethod != null) {
      if (methodInterceptors.containsKey(postConstructMethod.getName())) {
        createInvocationContext(bean, postConstructMethod, null,
            beanEJBAnnotation.getMethodInterceptors().get(postConstructMethod.getName()),
            beanEJBAnnotation.getClassInterceptors()).proceed();
      } else {
        postConstructMethod.invoke(bean);
      }
    }
    // TODO 目前不支持 PreDestroy
  }

  /**
   * 得到 action 所有的公共方法名的 {@link Set}
   *
   * @param clazz action 的 {@link Class} 对象。
   * @return 指定 clazz 的 action 的所有的公共方法名的 {@link Set}
   */
  public static Set<String> getActionPublicMethodNames(Class<?> clazz) {
    Set<String> methodSet = ACTION_PUBLIC_METHODS_CACHE.get(clazz);
    if (methodSet == null) {
      synchronized (ACTION_PUBLIC_METHODS_CACHE) {
        if ((methodSet = ACTION_PUBLIC_METHODS_CACHE.get(clazz)) == null) {
          Method[] methods = clazz.getMethods();
          methodSet = new HashSet<String>();
          for (Method method : methods) {
            methodSet.add(method.getName());
          }
          ACTION_PUBLIC_METHODS_CACHE.put(clazz, methodSet);
        }
      }
    }
    return methodSet;
  }

}
TOP

Related Classes of cn.agrael.struts.plugin.ejb3.StrutsEJBUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.