JsonFileCompare.java 2.95 KB
Newer Older
王品堯's avatar
王品堯 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class JsonFileCompare {

  public static void main(String[] args) {


    try {
      ObjectMapper objectMapper = new ObjectMapper();
      Path originPath = Paths.get(args[0]);
      JsonNode twJson = objectMapper.readTree(new String(Files.readAllBytes(originPath)));
      Set<String> originSet = new HashSet<>();
      addKeys("", twJson, originSet, new ArrayList<>());

      IntStream.range(1, args.length).forEach(i -> findMissingKeys(Paths.get(args[i]), originSet));

    } catch (Exception e) {
      System.err.println(args[0] + " is not exists or not json files.");
      System.exit(1);
    }
  }

  public static void addKeys(String currentPath, JsonNode jsonNode, Set set, List<Integer> suffix) {
    if (jsonNode.isObject()) {
      ObjectNode objectNode = (ObjectNode) jsonNode;
      Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
      String pathPrefix = currentPath.isEmpty() ? "" : currentPath + "-";

      while (iter.hasNext()) {
        Map.Entry<String, JsonNode> entry = iter.next();
        addKeys(pathPrefix + entry.getKey(), entry.getValue(), set, suffix);
      }
    } else if (jsonNode.isArray()) {
      ArrayNode arrayNode = (ArrayNode) jsonNode;

      for (int i = 0; i < arrayNode.size(); i++) {
        suffix.add(i + 1);
        addKeys(currentPath, arrayNode.get(i), set, suffix);

        if (i + 1 < arrayNode.size()) {
          suffix.remove(arrayNode.size() - 1);
        }
      }

    } else if (jsonNode.isValueNode()) {
      if (currentPath.contains("-")) {
        for (int i = 0; i < suffix.size(); i++) {
          currentPath += "-" + suffix.get(i);
        }
      }
      set.add(currentPath);
    }
  }

  public static void findMissingKeys(Path targetPath, Set<String> originSet) {
    if (!targetPath.toFile().exists()) return;
    try {
      Set<String> targetSet = new HashSet<>();
      ObjectMapper objectMapper = new ObjectMapper();
      JsonNode json = objectMapper.readTree(new String(Files.readAllBytes(targetPath)));
      addKeys("", json, targetSet, new ArrayList<>());

      Set<String> missingKey =
          originSet
              .parallelStream()
              .filter(key -> !targetSet.contains(key))
              .collect(Collectors.toSet());
      if (!missingKey.isEmpty()) {
        System.err.println("Missing Key on " + targetPath.toString());
        System.err.println("Missing Keys: ");
        missingKey.stream().sorted().forEach(System.err::println);
        System.exit(1);
      }
    } catch (Exception e) {
      System.err.println(targetPath.toString() + " is not json files.");
      System.exit(1);
    }
  }
}