public static Hashtable getAttachments(Message message) throws JMSException {
   if (!message.propertyExists(MessagePropertyNames.ATTACHMENT_TABLE)) {
     return ATTACHMENT_TABLE_DEF;
   }
   Hashtable attachments = new Hashtable();
   attachments.putAll((Map) message.getObjectProperty(MessagePropertyNames.ATTACHMENT_TABLE));
   return attachments;
 }
  public static Object getDataEntry(Message message, Object name) throws JMSException {
    if (!message.propertyExists(MessagePropertyNames.DATA_TABLE)) {
      return DATA_PROP_DEF;
    }

    Hashtable datTable = (Hashtable) message.getObjectProperty(MessagePropertyNames.DATA_TABLE);

    return datTable.get(name);
  }
  public static Object getAttachment(Message message, String name) throws JMSException {
    if (!message.propertyExists(MessagePropertyNames.ATTACHMENT_TABLE)) {
      return ATTACHMENT_PROP_DEF;
    }

    Hashtable attachmentTable;
    attachmentTable = (Hashtable) message.getObjectProperty(MessagePropertyNames.ATTACHMENT_TABLE);
    return attachmentTable.get(name);
  }
  public static void addDataEntry(Message message, Object name, Object value) throws JMSException {
    Hashtable dataTable = null;

    if (!message.propertyExists(MessagePropertyNames.DATA_TABLE)) {
      dataTable = new Hashtable();
    } else {
      dataTable = (Hashtable) message.getObjectProperty(MessagePropertyNames.DATA_TABLE);
    }

    dataTable.put(name, value);

    if (!message.propertyExists(MessagePropertyNames.DATA_TABLE)) {
      message.setObjectProperty(MessagePropertyNames.DATA_TABLE, dataTable);
    }
  }
  public static void addAttachment(Message message, Object name, Object value) throws JMSException {
    Hashtable headerTable = null;

    if (!message.propertyExists(MessagePropertyNames.ATTACHMENT_TABLE)) {
      headerTable = new Hashtable();
    } else {
      headerTable = (Hashtable) message.getObjectProperty(MessagePropertyNames.ATTACHMENT_TABLE);
    }

    headerTable.put(name, value);

    if (!message.propertyExists(MessagePropertyNames.ATTACHMENT_TABLE)) {
      message.setObjectProperty(MessagePropertyNames.ATTACHMENT_TABLE, headerTable);
    }
  }
  /**
   * Get the JMS reply destination specified by the given URL from the context
   *
   * @param context the Context to lookup
   * @param url URL
   * @return the JMS destination, or null if it does not exist
   */
  private Destination getReplyDestination(Context context, String url) {
    String replyDestinationName = properties.get(JMSConstants.PARAM_REPLY_DESTINATION);
    if (log.isDebugEnabled()) {
      log.debug(
          "Lookup the JMS destination "
              + replyDestinationName
              + " of type "
              + replyDestinationType
              + " extracted from the URL "
              + JMSUtils.maskURLPasswordAndCredentials(url));
    }

    try {
      return JMSUtils.lookupDestination(context, replyDestinationName, replyDestinationType);
    } catch (NamingException e) {
      handleException(
          "Couldn't locate the JMS destination "
              + replyDestinationName
              + " of type "
              + replyDestinationType
              + " extracted from the URL "
              + JMSUtils.maskURLPasswordAndCredentials(url),
          e);
    }

    // never executes but keeps the compiler happy
    return null;
  }
  /**
   * Get the referenced ConnectionFactory using the properties from the context
   *
   * @param context the context to use for lookup
   * @param props the properties which contains the JNDI name of the factory
   * @return the connection factory
   */
  private ConnectionFactory getConnectionFactory(Context context, Hashtable<String, String> props) {
    try {

      String conFacJndiName = props.get(JMSConstants.PARAM_CONFAC_JNDI_NAME);
      if (conFacJndiName != null) {
        return JMSUtils.lookup(context, ConnectionFactory.class, conFacJndiName);
      } else {
        handleException("Connection Factory JNDI name cannot be determined");
      }
    } catch (NamingException e) {
      handleException("Failed to look up connection factory from JNDI", e);
    }
    return null;
  }
  /**
   * Creates and instance using the given URL
   *
   * @param targetEPR the target EPR
   */
  JMSOutTransportInfo(String targetEPR) {

    this.targetEPR = targetEPR;
    properties = BaseUtils.getEPRProperties(targetEPR);
    String destinationType = properties.get(JMSConstants.PARAM_DEST_TYPE);
    if (destinationType != null) {
      setDestinationType(destinationType);
    }

    String replyDestinationType = properties.get(JMSConstants.PARAM_REPLY_DEST_TYPE);
    if (replyDestinationType != null) {
      setReplyDestinationType(replyDestinationType);
    }

    replyDestinationName = properties.get(JMSConstants.PARAM_REPLY_DESTINATION);
    contentTypeProperty = properties.get(JMSConstants.CONTENT_TYPE_PROPERTY_PARAM);
    cacheLevel = getCacheLevel(properties.get(JMSConstants.PARAM_CACHE_LEVEL));

    jmsSpecVersion =
        properties.get(JMSConstants.JMS_SPEC_VERSION) != null
            ? properties.get(JMSConstants.JMS_SPEC_VERSION)
            : "1.0.2b";
  }
  /**
   * Create a one time MessageProducer for this JMS OutTransport information. For simplicity and
   * best compatibility, this method uses only JMS 1.0.2b API. Please be cautious when making any
   * changes
   *
   * @return a JMSSender based on one-time use resources
   * @throws JMSException on errors, to be handled and logged by the caller
   */
  public JMSMessageSender createJMSSender(MessageContext msgCtx) throws JMSException {

    // digest the targetAddress and locate CF from the EPR
    loadConnectionFactoryFromProperties();

    // create a one time connection and session to be used
    String user = properties != null ? properties.get(JMSConstants.PARAM_JMS_USERNAME) : null;
    String pass = properties != null ? properties.get(JMSConstants.PARAM_JMS_PASSWORD) : null;

    QueueConnectionFactory qConFac = null;
    TopicConnectionFactory tConFac = null;

    int destType = -1;
    // TODO: there is something missing here for destination type generic
    if (JMSConstants.DESTINATION_TYPE_QUEUE.equals(destinationType)) {
      destType = JMSConstants.QUEUE;
      qConFac = (QueueConnectionFactory) connectionFactory;

    } else if (JMSConstants.DESTINATION_TYPE_TOPIC.equals(destinationType)) {
      destType = JMSConstants.TOPIC;
      tConFac = (TopicConnectionFactory) connectionFactory;
    } else {
      // treat jmsdestination type=queue(default is queue)
      destType = JMSConstants.QUEUE;
      qConFac = (QueueConnectionFactory) connectionFactory;
    }

    if (msgCtx.getProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER) != null) {
      XAConnection connection = null;
      if (user != null && pass != null) {
        if (qConFac != null) {
          connection = ((XAConnectionFactory) qConFac).createXAConnection(user, pass);
        } else if (tConFac != null) {
          connection = ((XAConnectionFactory) tConFac).createXAConnection(user, pass);
        }
      } else {
        if (qConFac != null) {
          connection = ((XAConnectionFactory) qConFac).createXAConnection();
        } else if (tConFac != null) {
          connection = ((XAConnectionFactory) tConFac).createXAConnection();
        }
      }

      if (connection == null) {
        connection = ((XAConnectionFactory) qConFac).createXAConnection();
      }

      XASession session = null;
      MessageProducer producer = null;

      if (connection != null) {
        if (destType == JMSConstants.QUEUE) {
          session = connection.createXASession();
          producer = session.createProducer(destination);
        } else {
          session = connection.createXASession();
          producer = session.createProducer(destination);
        }
      }

      XAResource xaResource = session.getXAResource();
      TransactionManager tx = null;
      Xid xid1 = null;
      Transaction transaction = null;
      java.util.UUID uuid = java.util.UUID.randomUUID();

      try {
        tx = (TransactionManager) msgCtx.getProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER);
        transaction = tx.getTransaction();
        msgCtx.setProperty(JMSConstants.JMS_XA_TRANSACTION_MANAGER, tx);
        msgCtx.setProperty(JMSConstants.JMS_XA_TRANSACTION, transaction);
        xid1 =
            new JMSXid(
                JMSConstants.JMS_XA_TRANSACTION_PREFIX.getBytes(StandardCharsets.UTF_8),
                1,
                uuid.toString().getBytes());
        msgCtx.setProperty("XID", xid1);
        xaResource.start(xid1, XAResource.TMNOFLAGS);
      } catch (SystemException e) {
        handleException("Error Occurred during starting getting Transaction.", e);
      } catch (XAException e) {
        handleException("Error Occurred during starting XA resource.", e);
      }
      return new JMSMessageSender(
          connection,
          session,
          producer,
          destination,
          jmsConnectionFactory == null ? this.cacheLevel : jmsConnectionFactory.getCacheLevel(),
          jmsSpecVersion,
          destType == -1 ? null : destType == JMSConstants.QUEUE ? Boolean.TRUE : Boolean.FALSE,
          transaction,
          xid1,
          xaResource);
    } else {
      Connection connection = null;
      if (user != null && pass != null) {
        if (qConFac != null) {
          connection = qConFac.createQueueConnection(user, pass);
        } else if (tConFac != null) {
          connection = tConFac.createTopicConnection(user, pass);
        }
      } else {
        if (qConFac != null) {
          connection = qConFac.createQueueConnection();
        } else if (tConFac != null) {
          connection = tConFac.createTopicConnection();
        }
      }

      if (connection == null) {
        connection = jmsConnectionFactory != null ? jmsConnectionFactory.getConnection() : null;
      }

      Session session = null;
      MessageProducer producer = null;

      if (connection != null) {
        if (destType == JMSConstants.QUEUE) {
          session =
              ((QueueConnection) connection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          producer = ((QueueSession) session).createSender((Queue) destination);
        } else {
          session =
              ((TopicConnection) connection).createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
          producer = ((TopicSession) session).createPublisher((Topic) destination);
        }
      }
      return new JMSMessageSender(
          connection,
          session,
          producer,
          destination,
          jmsConnectionFactory == null ? this.cacheLevel : jmsConnectionFactory.getCacheLevel(),
          jmsSpecVersion,
          destType == -1 ? null : destType == JMSConstants.QUEUE ? Boolean.TRUE : Boolean.FALSE);
    }
  }