/**
   * Get a permanent link to a given action on a bean
   *
   * @param bean Bean handler that will perform the action
   * @param action Bean's method that will be invoked
   * @param params Extra parameters for link
   * @return A link url to a bean action, independent on the page.
   */
  public String getPermanentLink(String bean, String action, Map params) {
    try {
      BeanHandler element = (BeanHandler) CDIBeanLocator.getBeanByNameOrType(bean);
      if (element == null) throw new RuntimeException("Bean '" + bean + "' not found.");

      StringBuffer sb = new StringBuffer();
      String base =
          RequestContext.lookup().getRequest().getRequestObject().getContextPath()
              + "/"
              + COMMAND_RUNNER;
      sb.append(base).append("?");
      params.put(FactoryURL.PARAMETER_BEAN, element.getBeanName());
      params.put(FactoryURL.PARAMETER_ACTION, action);
      sb.append(getParamsMarkup(params));
      element.setEnabledForActionHandling(true);
      return postProcessURL(sb).toString();
    } catch (ClassCastException cce) {
      log.error("Bean " + bean + " is not a BeanHandler.");
      return "#";
    }
  }
  /**
   * Generate a link to a factory component action
   *
   * @param beanName Factory component that will perform the action
   * @param action Bean's property (method) that will be invoked
   * @param params Extra parameters for link
   * @return A link url to a bean action
   */
  public String getMarkup(String beanName, String action, Map params) {
    try {
      if (params == null) params = new HashMap();
      Panel panel = RequestContext.lookup().getActivePanel();
      if (panel != null) {
        params.put(Parameters.DISPATCH_IDPANEL, panel.getPanelId());
        params.put(Parameters.DISPATCH_ACTION, "_factory");
      }

      StringBuffer sb = new StringBuffer();
      sb.append(_getServletMapping()).append("?");
      BeanHandler bean = (BeanHandler) CDIBeanLocator.getBeanByNameOrType(beanName);
      params.put(FactoryURL.PARAMETER_BEAN, bean.getBeanName());
      params.put(FactoryURL.PARAMETER_ACTION, bean.getActionName(action));
      sb.append(getParamsMarkup(params));
      bean.setEnabledForActionHandling(true);
      return postProcessURL(sb).toString();
    } catch (ClassCastException cce) {
      log.error("Bean " + beanName + " is not a BeanHandler.");
      return "#";
    }
  }