Json sorting

This commit is contained in:
Brady 2018-10-12 19:47:13 -05:00
parent 416fea2aa5
commit 24f18f0ac2
No known key found for this signature in database
GPG Key ID: 73A788379A197567

View File

@ -17,13 +17,16 @@
package baritone.gradle.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.google.gson.*;
import com.google.gson.internal.LazilyParsedNumber;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@ -38,14 +41,6 @@ import java.util.stream.Collectors;
public class Determinizer {
public static void main(String... args) throws IOException {
/*
haha yeah can't relate
unzip -p build/libs/baritone-$VERSION.jar "mixins.baritone.refmap.json" | jq --sort-keys -c -M '.' > mixins.baritone.refmap.json
zip -u build/libs/baritone-$VERSION.jar mixins.baritone.refmap.json
rm mixins.baritone.refmap.json
*/
System.out.println("Running Determinizer");
System.out.println(" Input path: " + args[0]);
System.out.println(" Output path: " + args[1]);
@ -67,7 +62,12 @@ public class Determinizer {
JarEntry clone = new JarEntry(entry.getName());
clone.setTime(0);
jos.putNextEntry(clone);
copy(jarFile.getInputStream(entry), jos);
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
copy(writeSorted(object), jos);
} else {
copy(jarFile.getInputStream(entry), jos);
}
}
jos.finish();
@ -82,4 +82,100 @@ public class Determinizer {
os.write(buffer, 0, len);
}
}
private static void copy(String s, OutputStream os) throws IOException {
os.write(s.getBytes());
}
private static String writeSorted(JsonObject in) throws IOException {
StringWriter writer = new StringWriter();
JsonWriter jw = new JsonWriter(writer);
JSON_ELEMENT.write(jw, in);
return writer.toString() + "\n";
}
/**
* All credits go to GSON and its contributors. GSON is licensed under the Apache 2.0 License.
* This implementation has been modified to write {@link JsonObject} keys in order.
*
* @see <a href="https://github.com/google/gson/blob/master/LICENSE">GSON License</a>
* @see <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java#L698">Original Source</a>
*/
private static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
@Override
public JsonElement read(JsonReader in) throws IOException {
switch (in.peek()) {
case STRING:
return new JsonPrimitive(in.nextString());
case NUMBER:
String number = in.nextString();
return new JsonPrimitive(new LazilyParsedNumber(number));
case BOOLEAN:
return new JsonPrimitive(in.nextBoolean());
case NULL:
in.nextNull();
return JsonNull.INSTANCE;
case BEGIN_ARRAY:
JsonArray array = new JsonArray();
in.beginArray();
while (in.hasNext()) {
array.add(read(in));
}
in.endArray();
return array;
case BEGIN_OBJECT:
JsonObject object = new JsonObject();
in.beginObject();
while (in.hasNext()) {
object.add(in.nextName(), read(in));
}
in.endObject();
return object;
case END_DOCUMENT:
case NAME:
case END_OBJECT:
case END_ARRAY:
default:
throw new IllegalArgumentException();
}
}
@Override
public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) {
out.nullValue();
} else if (value.isJsonPrimitive()) {
JsonPrimitive primitive = value.getAsJsonPrimitive();
if (primitive.isNumber()) {
out.value(primitive.getAsNumber());
} else if (primitive.isBoolean()) {
out.value(primitive.getAsBoolean());
} else {
out.value(primitive.getAsString());
}
} else if (value.isJsonArray()) {
out.beginArray();
for (JsonElement e : value.getAsJsonArray()) {
write(out, e);
}
out.endArray();
} else if (value.isJsonObject()) {
out.beginObject();
List<Map.Entry<String, JsonElement>> entries = new ArrayList<>(value.getAsJsonObject().entrySet());
entries.sort(Comparator.comparing(Map.Entry::getKey));
for (Map.Entry<String, JsonElement> e : entries) {
out.name(e.getKey());
write(out, e.getValue());
}
out.endObject();
} else {
throw new IllegalArgumentException("Couldn't write " + value.getClass());
}
}
};
}