/**
   * Translate the given code into some message from the application dictionary. It searches first
   * in AD_Message table and if there are not matchings then in AD_Element table.
   *
   * @param strCode String with the search key to search.
   * @return String with the translated message.
   */
  public static String messageBD(String strCode) {
    String strMessage = "";
    final String strLanguageId = OBContext.getOBContext().getLanguage().getId();

    // Search strCode in AD_Message table.
    try {
      OBContext.setAdminMode(false);
      log4j.debug("messageBD - Message Code: " + strCode);
      OBCriteria<Message> obcMessage = OBDal.getInstance().createCriteria(Message.class);
      obcMessage.add(Restrictions.eq(Message.PROPERTY_SEARCHKEY, strCode).ignoreCase());
      if (obcMessage.count() > 0) {
        Message msg = obcMessage.list().get(0);
        strMessage = msg.getMessageText();
        for (MessageTrl msgTrl : msg.getADMessageTrlList()) {
          if (DalUtil.getId(msgTrl.getLanguage()).equals(strLanguageId)) {
            strMessage = msgTrl.getMessageText();
            break;
          }
        }
      }
    } catch (final Exception ignore) {
      log4j.error("Error getting message", ignore);
    } finally {
      OBContext.restorePreviousMode();
    }
    log4j.debug("messageBD - Message description: " + strMessage);
    // if message is still empty search in AD_Element
    if ("".equals(strMessage)) {
      try {
        OBContext.setAdminMode(false);
        OBCriteria<Element> obcElement = OBDal.getInstance().createCriteria(Element.class);
        obcElement.add(Restrictions.eq(Element.PROPERTY_DBCOLUMNNAME, strCode).ignoreCase());
        if (obcElement.count() > 0) {
          Element element = obcElement.list().get(0);
          strMessage = element.getName();
          for (ElementTrl elementTrl : element.getADElementTrlList()) {
            if (DalUtil.getId(elementTrl.getLanguage()).equals(strLanguageId)) {
              strMessage = elementTrl.getName();
            }
          }
        }
      } catch (final Exception e) {
        log4j.error("Error getting message", e);
        strMessage = strCode;
      } finally {
        OBContext.restorePreviousMode();
      }
    }
    if ("".equals(strMessage)) {
      strMessage = strCode;
    }
    strMessage = Replace.replace(Replace.replace(strMessage, "\n", "\\n"), "\"", "&quot;");
    return strMessage;
  }
  /**
   * Returns a message in the right language with parameter substitution. Each occurence of a %
   * parameter (%0, %1 etc) is replaced with the corresponding parameter value. in the params array.
   *
   * @param key the key of the message
   * @param params the parameters to substitute in the message
   * @return the translated message with the parameters substituted
   */
  public static String getI18NMessage(String key, String[] params) {
    OBContext.setAdminMode();
    try {

      // first read the labels from the base table
      final OBQuery<Message> messages =
          OBDal.getInstance().createQuery(Message.class, Message.PROPERTY_SEARCHKEY + "=:key");
      messages.setNamedParameter("key", key);
      if (messages.list().isEmpty()) {
        return null;
      }

      if (messages.list().size() > 1) {
        log4j.warn("More than one message found using key " + key);
      }

      // pick the first one
      final Message message = messages.list().get(0);
      String label = message.getMessageText();
      final String languageId = OBContext.getOBContext().getLanguage().getId();
      for (MessageTrl messageTrl : message.getADMessageTrlList()) {
        if (DalUtil.getId(messageTrl.getLanguage()).equals(languageId)) {
          label = messageTrl.getMessageText();
          break;
        }
      }
      // parameter substitution
      if (params != null && params.length > 0) {
        int cnt = 0;
        for (String param : params) {
          label = label.replace("%" + cnt++, param);
        }
      }
      return label;
    } catch (Exception e) {
      throw new OBException("Exception when getting message for key: " + key, e);
    } finally {
      OBContext.restorePreviousMode();
    }
  }