/**
   * handle action class
   *
   * @param clsName
   * @throws Exception
   */
  public boolean handleClass(String clsName) {

    // log.debug("handleClass -> " + clsName);

    Class<?> cls = null;
    try {
      cls = Class.forName(clsName);

      if (cls == null) return false;

      String simpleName = cls.getSimpleName();
      Controller controlAnn = cls.getAnnotation(Controller.class);
      if (controlAnn == null
          && !simpleName.endsWith("Controller")
          && !simpleName.endsWith("Action")
          && !simpleName.endsWith("Control")) return false;

      String moduleName =
          CommonUtil.toLowCaseFirst(simpleName.replace("Controller", "").replace("Control", ""));
      if (simpleName.endsWith("Action")) {
        moduleName = "";
      }

      Object obj = null;
      try {
        if (cls.getAnnotation(Singleton.class) != null) {
          obj = SingleBeanCache.get(cls.getName());
          if (obj == null) {
            obj = cls.newInstance();
            SingleBeanCache.add(cls.getName(), obj);
          }
        } else obj = cls.newInstance();

      } catch (Error er) {
        // er.printStackTrace();
        log.debug("the action class new instance failued -> " + clsName + " | " + er.toString());
        return false;
      } catch (Exception e) {
        // e.printStackTrace();
        log.warn("the action class new instance failued -> " + clsName + " | " + e.toString());
        return false;
      }

      ReflectUtil ru = new ReflectUtil(obj);
      Method[] ms = ru.getMethods();
      if (ms == null) return false;

      // 扫描方法的注解信息
      for (Method m : ms) {
        if (m.getModifiers() != 1) continue;

        Path path = m.getAnnotation(Path.class);

        if (path == null) {
          String methodName = m.getName();
          Method getter = ru.getGetter(methodName.replace("get", ""));
          Method setter = ru.getSetter(methodName.replace("set", ""));
          // 默认下setter和getter不作为action方法
          if (getter != null || setter != null) continue;
        }

        handleActionConfigInfo(ru, cls, m, moduleName);
      }
    } catch (Error e) {
      return false;
    } catch (Exception e) {
      return false;
    }

    return true;
  }
  /**
   * 解析 URI Mapping 后部分
   *
   * @param moduleName
   * @param m
   * @return
   */
  private ActionConfigBean parseUriMappingSuffix(String moduleName, Method m) {
    ActionConfigBean acb = new ActionConfigBean();

    String methodName = m.getName();
    String fullName = m.toString();
    log.debug("parse action.method --> " + fullName);

    String uriMapping = null;
    Path m_path = m.getAnnotation(Path.class);
    if (methodName.startsWith(ActionMethod.PREFIX)) {
      uriMapping = methodName.substring(ActionMethod.PREFIX.length());
      // doUriBindParam1AndParam2JoinUriAtPostOrGet
      String at = null;
      int indexOfAt = methodName.indexOf(ActionMethod.AT);
      if (indexOfAt != -1) {
        at = methodName.substring(indexOfAt + ActionMethod.AT.length());
        if (methodName.startsWith(ActionMethod.PREFIX))
          uriMapping = uriMapping.substring(0, uriMapping.indexOf(ActionMethod.AT));
        String[] httpMethods = at.split(ActionMethod.OR);
        StringBuilder sb = new StringBuilder();
        for (String httpMethod : httpMethods) {
          if (sb.length() > 0) sb.append("|");

          sb.append(httpMethod.toUpperCase());
        }
        if (sb.length() > 0) {
          acb.setHttpMethod(sb.toString());
        }
      }
      String join = "";
      String bind;
      int indexOfBind = methodName.indexOf(ActionMethod.BIND);
      if (indexOfBind != -1) {
        if (indexOfAt != -1 && indexOfAt > indexOfBind) {
          bind = methodName.substring(indexOfBind + ActionMethod.BIND.length(), indexOfAt);
        } else {
          bind = methodName.substring(indexOfBind + ActionMethod.BIND.length());
        }

        uriMapping = uriMapping.substring(0, uriMapping.indexOf(ActionMethod.BIND));

        int indexOfJoin = bind.indexOf(ActionMethod.JOIN);
        if (indexOfJoin != -1) {
          String[] joins = bind.split(ActionMethod.JOIN);
          if (joins.length > 1) {
            bind = joins[0];
            join = joins[1];
          }
        }

        String[] pathParams = bind.split(ActionMethod.AND);
        StringBuilder pathParamSB = new StringBuilder();
        for (int i = 0; i < pathParams.length; i++) {
          pathParams[i] = CommonUtil.toLowCaseFirst(pathParams[i]);
          pathParamSB.append("/{").append(pathParams[i]).append("}");
        }

        if (pathParamSB.length() > 0) uriMapping = uriMapping + pathParamSB.toString();

        acb.setPathParams(pathParams);
      }

      uriMapping = CommonUtil.toLowCaseFirst(uriMapping);
      uriMapping = CommonUtil.hump2ohter(uriMapping, "-");

      if (join.length() > 0) {
        join = CommonUtil.toLowCaseFirst(join);
        join = CommonUtil.hump2ohter(join, "-");
        uriMapping = uriMapping + "/" + join;
      }

    } else if (m_path == null) {
      /* 8 个默认方法 */
      ActionConfigBean defaultAcb = parseDefaultActionConfig(methodName, moduleName);
      if (defaultAcb != null) {
        acb.setHttpMethod(defaultAcb.getHttpMethod());
        acb.getResult().addAll(defaultAcb.getResult());

        uriMapping = defaultAcb.getUriMapping();
      } else {

        String info =
            fullName
                + " does not starts with '"
                + ActionMethod.PREFIX
                + "' so that can not be a valid action uri mapping";
        log.debug(info);
        return null;
      }
    }

    if (m_path != null) {
      uriMapping = CommonUtil.parsePropValue(m_path.value());
    }

    acb.setUriMapping(uriMapping);
    return acb;
  }