content: package com.taobao.qa.ruleengine.utils;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.web.multipart.MultipartFile;
  
  import java.io.*;
  import java.nio.file.*;
  import java.nio.file.attribute.BasicFileAttributes;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Vector;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  public class ExpressFileReader {
      private static final Logger logger  = LoggerFactory.getLogger(ExpressFileReader.class);
  
      /**
       * 直接从文件系统读取文件
       * @throws IOException
       */
      public static Map<String,String> loadRuleExpressFromFile(String filename) throws IOException {
          logger.debug("[Enter]loadRuleExpressFromFile()");
          BufferedReader reader = new BufferedReader(new FileReader(filename));
          return loadFromBufferedReader(reader);
      }
  
      /**
       * 处理从前端上传的文件
       * @throws IOException
       */
      public static Map<String,String> loadRuleExpressFromMultipartFile(MultipartFile multipartFile) throws IOException {
          logger.debug("[Enter]loadRuleExpressFromMultipartFile()");
          InputStreamReader is = new InputStreamReader(multipartFile.getInputStream());
          BufferedReader br = new BufferedReader(is);
          return loadFromBufferedReader(br);
      }
  
      private static Map<String,String> loadFromBufferedReader(BufferedReader reader) throws IOException {
          Pattern sectionPattern = Pattern.compile("^\\s*\\[(.+)\\]");
          Map<String,String> output = new HashMap<String, String>();
  
          StringBuffer sectionContent = new StringBuffer("");
          String sectionName = null;
          String line;
  
          try {
              while ((line = reader.readLine()) != null) {
                  // remove BOM
                  line = line.replace("\uFEFF","");
                  String lineTrimed = line.trim();
  
                  // 忽略空白行或#开头的注释行
                  if(lineTrimed.isEmpty() || lineTrimed.startsWith("#")) {
                      continue;
                  }
  
                  // 判断是否是Section Line
                  Matcher m = sectionPattern.matcher(lineTrimed);
  
                  // 发现新的section
                  if (m.find()) {
                      // 第一个section
                      if(sectionName == null) {
                          // 获取sectionName(大小写不敏感)
                          sectionName = m.group(1).toLowerCase();
  
                          // sectionContent清零
                          sectionContent.setLength(0);
                          continue;
                      }
  
                      // 非第一个section
                      // 记录最近的sectionContent(trim 结尾的\n)
                      output.put(sectionName, sectionContent.toString().trim());
  
                      // sectionContent清零
                      sectionContent.setLength(0);
  
                      // 获取新的sectionName(大小写不敏感)
                      sectionName = m.group(1).toLowerCase();
  
                      // 如果sectionName有重复，则抛异常
                      if (output.containsKey(sectionName)) {
                          String errMsg = String.format("存在重名Section \"%s\"", sectionName);
                          throw new IllegalStateException(errMsg);
                      }
                  }
                  // 当前line是sectionContent
                  else {
                      if (sectionName == null) {
                          String errMsg = "解析Rule Express失败:sectionName 还未初始化";
                          throw new IllegalStateException(errMsg);
                      }
                      sectionContent.append(line + "\n");
                  }
              }
  
              // 记录最后一个sectionContent(trim 结尾的\n)
              output.put(sectionName, sectionContent.toString().trim());
              return output;
          }
          finally {
              reader.close();
          }
      }
  
      public static List<String> getFileListWithGlobPattern(String glob,String location) throws IOException {
          final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob);
          List<String> outputFileList = new Vector<String>();
  
          Files.walkFileTree(Paths.get(location),new FileVisitor(pathMatcher,outputFileList));
  
          return outputFileList;
      }
  
      private static class FileVisitor extends SimpleFileVisitor<Path> {
          private PathMatcher pathMatcher;
          private List<String> outputFileList;
  
          public FileVisitor(PathMatcher matcher, List<String> outputFileList) {
              if(outputFileList == null || !outputFileList.isEmpty()) {
                  throw new IllegalArgumentException("outputFileList is null or is not empty");
              }
              this.pathMatcher = matcher;
              this.outputFileList = outputFileList;
          }
  
          public List<String> getOutputFileList() {
              return this.outputFileList;
          }
  
          @Override
          public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
              if(pathMatcher.matches(path)) {
                  //System.out.println(path);
                  outputFileList.add(path.toString());
              }
              return FileVisitResult.CONTINUE;
          }
  
          @Override
          public FileVisitResult visitFileFailed(Path file, IOException exc) {
              return FileVisitResult.CONTINUE;
          }
      }
  
  
      ////// Test
      public static void main(String[] args) throws IOException {
          System.out.println("Enter main...");
  
          List<String> output = getFileListWithGlobPattern("glob:**/DemoRule*.ql",".");
  
          System.out.println("Output:");
          System.out.println("=======");
          for(String item: output) {
              System.out.println(item);
          }
  
          System.out.println("Exit main...");
      }
  }
  