/**
   * Perform validation on namespace qualified attribute values if present. This includes the
   * validation of namespace presence and equality.
   *
   * @param receivedElement
   * @param receivedAttribute
   * @param sourceElement
   * @param sourceAttribute
   */
  private void doNamespaceQualifiedAttributeValidation(
      Node receivedElement, Node receivedAttribute, Node sourceElement, Node sourceAttribute) {
    String receivedValue = receivedAttribute.getNodeValue();
    String sourceValue = sourceAttribute.getNodeValue();

    if (receivedValue.contains(":") && sourceValue.contains(":")) {
      // value has namespace prefix set, do special QName validation
      String receivedPrefix = receivedValue.substring(0, receivedValue.indexOf(':'));
      String sourcePrefix = sourceValue.substring(0, sourceValue.indexOf(':'));

      Map<String, String> receivedNamespaces =
          XMLUtils.lookupNamespaces(receivedAttribute.getOwnerDocument());
      receivedNamespaces.putAll(XMLUtils.lookupNamespaces(receivedElement));

      if (receivedNamespaces.containsKey(receivedPrefix)) {
        Map<String, String> sourceNamespaces =
            XMLUtils.lookupNamespaces(sourceAttribute.getOwnerDocument());
        sourceNamespaces.putAll(XMLUtils.lookupNamespaces(sourceElement));

        if (sourceNamespaces.containsKey(sourcePrefix)) {
          Assert.isTrue(
              sourceNamespaces.get(sourcePrefix).equals(receivedNamespaces.get(receivedPrefix)),
              ValidationUtils.buildValueMismatchErrorMessage(
                  "Values not equal for attribute value namespace '" + receivedValue + "'",
                  sourceNamespaces.get(sourcePrefix),
                  receivedNamespaces.get(receivedPrefix)));

          // remove namespace prefixes as they must not form equality
          receivedValue = receivedValue.substring((receivedPrefix + ":").length());
          sourceValue = sourceValue.substring((sourcePrefix + ":").length());
        } else {
          throw new ValidationException(
              "Received attribute value '"
                  + receivedAttribute.getLocalName()
                  + "' describes namespace qualified attribute value,"
                  + " control value '"
                  + sourceValue
                  + "' does not");
        }
      }
    }

    Assert.isTrue(
        receivedValue.equals(sourceValue),
        ValidationUtils.buildValueMismatchErrorMessage(
            "Values not equal for attribute '" + receivedAttribute.getLocalName() + "'",
            sourceValue,
            receivedValue));
  }
 protected Map<String, Object> createPluginContextAttributes() {
   Map<String, Object> attributes = new HashMap<String, Object>();
   String bootVersion = CrshAutoConfiguration.class.getPackage().getImplementationVersion();
   if (bootVersion != null) {
     attributes.put("spring.boot.version", bootVersion);
   }
   attributes.put("spring.version", SpringVersion.getVersion());
   if (this.beanFactory != null) {
     attributes.put("spring.beanfactory", this.beanFactory);
   }
   if (this.environment != null) {
     attributes.put("spring.environment", this.environment);
   }
   return attributes;
 }
  /**
   * Validate namespaces in message. The method compares namespace declarations in the root element
   * of the received message to expected namespaces. Prefixes are important too, so differing
   * namespace prefixes will fail the validation.
   *
   * @param expectedNamespaces
   * @param receivedMessage
   */
  protected void validateNamespaces(
      Map<String, String> expectedNamespaces, Message receivedMessage) {
    if (CollectionUtils.isEmpty(expectedNamespaces)) {
      return;
    }

    if (receivedMessage.getPayload() == null
        || !StringUtils.hasText(receivedMessage.getPayload(String.class))) {
      throw new ValidationException(
          "Unable to validate message namespaces - receive message payload was empty");
    }

    log.info("Start XML namespace validation");

    Document received = XMLUtils.parseMessagePayload(receivedMessage.getPayload(String.class));

    Map<String, String> foundNamespaces =
        XMLUtils.lookupNamespaces(receivedMessage.getPayload(String.class));

    if (foundNamespaces.size() != expectedNamespaces.size()) {
      throw new ValidationException(
          "Number of namespace declarations not equal for node "
              + XMLUtils.getNodesPathName(received.getFirstChild())
              + " found "
              + foundNamespaces.size()
              + " expected "
              + expectedNamespaces.size());
    }

    for (Entry<String, String> entry : expectedNamespaces.entrySet()) {
      String namespace = entry.getKey();
      String url = entry.getValue();

      if (foundNamespaces.containsKey(namespace)) {
        if (!foundNamespaces.get(namespace).equals(url)) {
          throw new ValidationException(
              "Namespace '"
                  + namespace
                  + "' values not equal: found '"
                  + foundNamespaces.get(namespace)
                  + "' expected '"
                  + url
                  + "' in reference node "
                  + XMLUtils.getNodesPathName(received.getFirstChild()));
        } else {
          log.info(
              "Validating namespace " + namespace + " value as expected " + url + " - value OK");
        }
      } else {
        throw new ValidationException(
            "Missing namespace "
                + namespace
                + "("
                + url
                + ") in node "
                + XMLUtils.getNodesPathName(received.getFirstChild()));
      }
    }

    log.info("XML namespace validation finished successfully: All values OK");
  }