package me.osm.gazetter.utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Utility to calculate hashes for JSON objects
* */
public class JSONHash {
/**
* Write JSON object to string with members and arrays sorting
*
* @param obj target object
* @param ignoreKeys do not include this keys into result string (may be null)
* */
public static String asCanonicalString(Object obj, Set<String> ignoreKeys) {
StringBuilder sb = new StringBuilder();
traverse(obj, sb, ignoreKeys);
return sb.toString();
}
@SuppressWarnings("unchecked")
private static void traverse(Object obj, StringBuilder sb,
Set<String> ignoreKeys) {
if (obj instanceof JSONObject) {
JSONObject object = (JSONObject) obj;
List<String> keys = new ArrayList<String>();
keys.addAll(object.keySet());
Collections.sort(keys);
sb.append("{");
for(String key : keys) {
if(ignoreKeys == null || !ignoreKeys.contains(key)) {
sb.append("\"").append(key).append("\":{")
.append(asCanonicalString(object.get(key), ignoreKeys)).append("}");
}
}
sb.append("}");
}
else if (obj instanceof JSONArray) {
JSONArray array = (JSONArray) obj;
List<String> elements = new ArrayList<String>();
for(int i = 0; i < array.length(); i++) {
elements.add(asCanonicalString(array.get(i), ignoreKeys));
}
Collections.sort(elements);
sb.append("[");
sb.append(StringUtils.join(elements, ","));
sb.append("]");
}
else {
sb.append(obj);
}
}
}