|
1 | 1 | /*
|
2 |
| - * Copyright 2022 DiffPlug |
| 2 | + * Copyright 2022-2023 DiffPlug |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
17 | 17 |
|
18 | 18 | import java.io.IOException;
|
19 | 19 | import java.io.Serializable;
|
20 |
| -import java.io.StringWriter; |
21 |
| -import java.util.Collections; |
| 20 | +import java.lang.reflect.Constructor; |
| 21 | +import java.lang.reflect.InvocationTargetException; |
22 | 22 | import java.util.Objects;
|
23 | 23 |
|
24 | 24 | import com.diffplug.spotless.FormatterFunc;
|
|
28 | 28 |
|
29 | 29 | public class GsonStep {
|
30 | 30 | private static final String MAVEN_COORDINATES = "com.google.code.gson:gson";
|
| 31 | + private static final String INCOMPATIBLE_ERROR_MESSAGE = "There was a problem interacting with Gson; maybe you set an incompatible version?"; |
31 | 32 |
|
| 33 | + @Deprecated |
32 | 34 | public static FormatterStep create(int indentSpaces, boolean sortByKeys, boolean escapeHtml, String version, Provisioner provisioner) {
|
| 35 | + return create(new GsonConfig(sortByKeys, escapeHtml, indentSpaces, version), provisioner); |
| 36 | + } |
| 37 | + |
| 38 | + public static FormatterStep create(GsonConfig gsonConfig, Provisioner provisioner) { |
33 | 39 | Objects.requireNonNull(provisioner, "provisioner cannot be null");
|
34 |
| - return FormatterStep.createLazy("gson", () -> new State(indentSpaces, sortByKeys, escapeHtml, version, provisioner), State::toFormatter); |
| 40 | + return FormatterStep.createLazy("gson", () -> new State(gsonConfig, provisioner), State::toFormatter); |
35 | 41 | }
|
36 | 42 |
|
37 | 43 | private static final class State implements Serializable {
|
38 |
| - private static final long serialVersionUID = -1493479043249379485L; |
| 44 | + private static final long serialVersionUID = -3240568265160440420L; |
39 | 45 |
|
40 |
| - private final int indentSpaces; |
41 |
| - private final boolean sortByKeys; |
42 |
| - private final boolean escapeHtml; |
43 | 46 | private final JarState jarState;
|
| 47 | + private final GsonConfig gsonConfig; |
44 | 48 |
|
45 |
| - private State(int indentSpaces, boolean sortByKeys, boolean escapeHtml, String version, Provisioner provisioner) throws IOException { |
46 |
| - this.indentSpaces = indentSpaces; |
47 |
| - this.sortByKeys = sortByKeys; |
48 |
| - this.escapeHtml = escapeHtml; |
49 |
| - this.jarState = JarState.from(MAVEN_COORDINATES + ":" + version, provisioner); |
| 49 | + private State(GsonConfig gsonConfig, Provisioner provisioner) throws IOException { |
| 50 | + this.gsonConfig = gsonConfig; |
| 51 | + this.jarState = JarState.from(MAVEN_COORDINATES + ":" + gsonConfig.getVersion(), provisioner); |
50 | 52 | }
|
51 | 53 |
|
52 | 54 | FormatterFunc toFormatter() {
|
53 |
| - JsonWriterWrapper jsonWriterWrapper = new JsonWriterWrapper(jarState); |
54 |
| - JsonElementWrapper jsonElementWrapper = new JsonElementWrapper(jarState); |
55 |
| - JsonObjectWrapper jsonObjectWrapper = new JsonObjectWrapper(jarState, jsonElementWrapper); |
56 |
| - GsonBuilderWrapper gsonBuilderWrapper = new GsonBuilderWrapper(jarState); |
57 |
| - GsonWrapper gsonWrapper = new GsonWrapper(jarState, jsonElementWrapper, jsonWriterWrapper); |
58 |
| - |
59 |
| - Object gsonBuilder = gsonBuilderWrapper.serializeNulls(gsonBuilderWrapper.createGsonBuilder()); |
60 |
| - if (!escapeHtml) { |
61 |
| - gsonBuilder = gsonBuilderWrapper.disableHtmlEscaping(gsonBuilder); |
| 55 | + try { |
| 56 | + Class<?> formatterFunc = jarState.getClassLoader().loadClass("com.diffplug.spotless.glue.gson.GsonFormatterFunc"); |
| 57 | + Constructor<?> constructor = formatterFunc.getConstructor(GsonConfig.class); |
| 58 | + return (FormatterFunc) constructor.newInstance(gsonConfig); |
| 59 | + } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
| 60 | + | InstantiationException | IllegalAccessException | NoClassDefFoundError cause) { |
| 61 | + throw new IllegalStateException(INCOMPATIBLE_ERROR_MESSAGE, cause); |
62 | 62 | }
|
63 |
| - Object gson = gsonBuilderWrapper.create(gsonBuilder); |
64 |
| - |
65 |
| - return inputString -> { |
66 |
| - String result; |
67 |
| - if (inputString.isEmpty()) { |
68 |
| - result = ""; |
69 |
| - } else { |
70 |
| - Object jsonElement = gsonWrapper.fromJson(gson, inputString, jsonElementWrapper.getWrappedClass()); |
71 |
| - if (jsonElement == null) { |
72 |
| - throw new AssertionError(GsonWrapperBase.FAILED_TO_PARSE_ERROR_MESSAGE); |
73 |
| - } |
74 |
| - if (sortByKeys && jsonElementWrapper.isJsonObject(jsonElement)) { |
75 |
| - jsonElement = sortByKeys(jsonObjectWrapper, jsonElementWrapper, jsonElement); |
76 |
| - } |
77 |
| - try (StringWriter stringWriter = new StringWriter()) { |
78 |
| - Object jsonWriter = jsonWriterWrapper.createJsonWriter(stringWriter); |
79 |
| - jsonWriterWrapper.setIndent(jsonWriter, generateIndent(indentSpaces)); |
80 |
| - gsonWrapper.toJson(gson, jsonElement, jsonWriter); |
81 |
| - result = stringWriter + "\n"; |
82 |
| - } |
83 |
| - } |
84 |
| - return result; |
85 |
| - }; |
86 |
| - } |
87 |
| - |
88 |
| - private Object sortByKeys(JsonObjectWrapper jsonObjectWrapper, JsonElementWrapper jsonElementWrapper, Object jsonObject) { |
89 |
| - Object result = jsonObjectWrapper.createJsonObject(); |
90 |
| - jsonObjectWrapper.keySet(jsonObject).stream().sorted() |
91 |
| - .forEach(key -> { |
92 |
| - Object element = jsonObjectWrapper.get(jsonObject, key); |
93 |
| - if (jsonElementWrapper.isJsonObject(element)) { |
94 |
| - element = sortByKeys(jsonObjectWrapper, jsonElementWrapper, element); |
95 |
| - } |
96 |
| - jsonObjectWrapper.add(result, key, element); |
97 |
| - }); |
98 |
| - return result; |
99 |
| - } |
100 |
| - |
101 |
| - private String generateIndent(int indentSpaces) { |
102 |
| - return String.join("", Collections.nCopies(indentSpaces, " ")); |
103 | 63 | }
|
104 | 64 | }
|
105 | 65 |
|
|
0 commit comments