content: package com.alibaba.otter.canal.client.adapter.support;
  
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.nio.charset.StandardCharsets;
  import java.util.Arrays;
  import java.util.List;
  import java.util.Map;
  import java.util.Properties;
  
  import org.apache.commons.lang.StringUtils;
  import org.springframework.boot.context.properties.bind.Bindable;
  import org.springframework.boot.context.properties.bind.Binder;
  import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
  import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
  import org.springframework.boot.env.YamlPropertySourceLoader;
  import org.springframework.boot.origin.OriginTrackedValue;
  import org.springframework.core.env.PropertySource;
  import org.springframework.core.io.ByteArrayResource;
  import org.springframework.core.io.ClassPathResource;
  import org.springframework.core.io.Resource;
  import org.springframework.util.PropertyPlaceholderHelper;
  
  public class YamlUtils {
  
      public static <T> T resourceYmlToObj(String resource, String prefix, Class<T> clazz) {
          if (!StringUtils.startsWithIgnoreCase(resource, "classpath:")) {
              resource = "classpath:" + resource;
          }
          ClassPathResource classPathResource = new ClassPathResource(resource);
  
          String content;
          try (InputStream inputStream = classPathResource.getInputStream()) {
  
              ByteArrayOutputStream result = new ByteArrayOutputStream();
              byte[] buffer = new byte[1024];
              int length;
              while ((length = inputStream.read(buffer)) != -1) {
                  result.write(buffer, 0, length);
              }
              content = result.toString("UTF-8");
          } catch (IOException e) {
              throw new RuntimeException(e);
          }
          return ymlToObj(prefix, content, clazz);
      }
  
      public static <T> T ymlToObj(String content, Class<T> clazz) {
          return ymlToObj("", content, clazz, null, null);
      }
  
      public static <T> T ymlToObj(String prefix, String content, Class<T> clazz) {
          return ymlToObj(prefix, content, clazz, null, null);
      }
  
      public static <T> T ymlToObj(String prefix, String content, Class<T> clazz, String charset) {
          return ymlToObj(prefix, content, clazz, charset, null);
      }
  
      public static <T> T ymlToObj(String prefix, String content, Class<T> clazz, String charset,
                                   Properties baseProperties) {
          try {
              prefix = StringUtils.trimToEmpty(prefix);
              byte[] contentBytes;
              if (charset == null) {
                  contentBytes = content.getBytes(StandardCharsets.UTF_8);
              } else {
                  contentBytes = content.getBytes(charset);
              }
              YamlPropertySourceLoader propertySourceLoader = new YamlPropertySourceLoader();
              Resource configResource = new ByteArrayResource(contentBytes);
              List<PropertySource<?>> propertySources = propertySourceLoader.load("manualBindConfig", configResource);
  
              if (propertySources == null || propertySources.isEmpty()) {
                  return null;
              }
  
              PropertySource<?> propertySource = propertySources.get(0);
  
              Properties properties = new Properties();
              if (baseProperties != null) {
                  properties.putAll(baseProperties);
              }
  
              properties.putAll((Map<?, ?>) propertySource.getSource());
  
              for (Map.Entry<Object, Object> entry : properties.entrySet()) {
                  Object value = entry.getValue();
                  if (value instanceof OriginTrackedValue) {
                      entry.setValue(((OriginTrackedValue) value).getValue());
                  }
              }
  
              ConfigurationPropertySource sources = new MapConfigurationPropertySource(properties);
              PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}");
              Binder binder = new Binder(Arrays.asList(sources), value -> {
                  if (value instanceof String) {
                      return propertyPlaceholderHelper.replacePlaceholders((String) value, baseProperties);
                  }
                  return value;
              });
              return binder.bind(prefix, Bindable.of(clazz)).get();
          } catch (Exception e) {
              throw new RuntimeException(e);
          }
      }
  }
  