|
17 | 17 |
|
18 | 18 | import java.io.IOException;
|
19 | 19 | import java.io.Serializable;
|
| 20 | +import java.lang.reflect.Constructor; |
20 | 21 | import java.lang.reflect.InvocationTargetException;
|
21 |
| -import java.lang.reflect.Method; |
22 | 22 | import java.util.Arrays;
|
23 | 23 | import java.util.List;
|
24 | 24 | import java.util.Objects;
|
|
32 | 32 | * Simple YAML formatter which reformats the file according to Jackson YAMLFactory.
|
33 | 33 | */
|
34 | 34 | // https://stackoverflow.com/questions/14515994/convert-json-string-to-pretty-print-json-output-using-jackson
|
35 |
| -public final class YamlJacksonStep { |
| 35 | +public class YamlJacksonStep { |
36 | 36 | static final String MAVEN_COORDINATE = "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:";
|
37 |
| - static final String DEFAULT_VERSION = "2.13.4"; |
| 37 | + // https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml |
| 38 | + static final String DEFAULT_VERSION = "2.14.1"; |
| 39 | + |
| 40 | + private YamlJacksonStep() {} |
38 | 41 |
|
39 | 42 | public static String defaultVersion() {
|
40 | 43 | return DEFAULT_VERSION;
|
@@ -69,89 +72,14 @@ private State(List<String> enabledFeatures,
|
69 | 72 | this.enabledFeatures = enabledFeatures;
|
70 | 73 | this.disabledFeatures = disabledFeatures;
|
71 | 74 |
|
72 |
| - this.jarState = JarState.from(MAVEN_COORDINATE + jacksonVersion, provisioner); |
| 75 | + this.jarState = JarState.from(YamlJacksonStep.MAVEN_COORDINATE + jacksonVersion, provisioner); |
73 | 76 | }
|
74 | 77 |
|
75 |
| - FormatterFunc toFormatter() { |
76 |
| - Class<?> jsonFactoryClass; |
77 |
| - Class<?> yamlFactoryClass; |
78 |
| - Class<?> objectMapperClass; |
79 |
| - |
80 |
| - Class<?> serializationFeatureClass; |
81 |
| - Method enableFeature; |
82 |
| - Method disableFeature; |
83 |
| - |
84 |
| - Method stringToNode; |
85 |
| - Method nodeToString; |
86 |
| - try { |
87 |
| - ClassLoader classLoader = jarState.getClassLoader(); |
88 |
| - jsonFactoryClass = classLoader.loadClass("com.fasterxml.jackson.core.JsonFactory"); |
89 |
| - yamlFactoryClass = classLoader.loadClass("com.fasterxml.jackson.dataformat.yaml.YAMLFactory"); |
90 |
| - |
91 |
| - objectMapperClass = classLoader.loadClass("com.fasterxml.jackson.databind.ObjectMapper"); |
92 |
| - |
93 |
| - // Configure the ObjectMapper |
94 |
| - // https://github.com/FasterXML/jackson-databind#commonly-used-features |
95 |
| - { |
96 |
| - serializationFeatureClass = classLoader.loadClass("com.fasterxml.jackson.databind.SerializationFeature"); |
97 |
| - enableFeature = objectMapperClass.getMethod("enable", serializationFeatureClass); |
98 |
| - disableFeature = objectMapperClass.getMethod("disable", serializationFeatureClass); |
99 |
| - } |
100 |
| - |
101 |
| - // https://stackoverflow.com/questions/25222327/deserialize-pojos-from-multiple-yaml-documents-in-a-single-file-in-jackson |
102 |
| - // List<ObjectNode> docs = mapper |
103 |
| - // .readValues<ObjectNode>(yamlParser, new TypeReference<ObjectNode> {}) |
104 |
| - // .readAll(); |
105 |
| - |
106 |
| - Class<?> jsonNodeClass = classLoader.loadClass("com.fasterxml.jackson.databind.JsonNode"); |
107 |
| - |
108 |
| - // This will transit with a JsonNode |
109 |
| - // A JsonNode may keep the comments from the input node |
110 |
| - stringToNode = objectMapperClass.getMethod("readTree", String.class); |
111 |
| - // Not 'toPrettyString' as one could require no INDENT_OUTPUT |
112 |
| - nodeToString = jsonNodeClass.getMethod("toPrettyString"); |
113 |
| - } catch (ClassNotFoundException | NoSuchMethodException e) { |
114 |
| - throw new IllegalStateException("There was a problem preparing org.json dependencies", e); |
115 |
| - } |
116 |
| - |
117 |
| - return s -> { |
118 |
| - if (s.isEmpty()) { |
119 |
| - return s; |
120 |
| - } |
121 |
| - |
122 |
| - Object yamlFactory = yamlFactoryClass.getConstructor().newInstance(); |
123 |
| - Object objectMapper = objectMapperClass.getConstructor(jsonFactoryClass).newInstance(yamlFactory); |
124 |
| - |
125 |
| - for (String feature : enabledFeatures) { |
126 |
| - // https://stackoverflow.com/questions/3735927/java-instantiating-an-enum-using-reflection |
127 |
| - Object indentOutput = Enum.valueOf(serializationFeatureClass.asSubclass(Enum.class), feature); |
128 |
| - |
129 |
| - enableFeature.invoke(objectMapper, indentOutput); |
130 |
| - } |
131 |
| - |
132 |
| - for (String feature : disabledFeatures) { |
133 |
| - // https://stackoverflow.com/questions/3735927/java-instantiating-an-enum-using-reflection |
134 |
| - Object indentOutput = Enum.valueOf(serializationFeatureClass.asSubclass(Enum.class), feature); |
135 |
| - |
136 |
| - disableFeature.invoke(objectMapper, indentOutput); |
137 |
| - } |
138 |
| - |
139 |
| - return format(objectMapper, stringToNode, nodeToString, s); |
140 |
| - }; |
| 78 | + FormatterFunc toFormatter() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, |
| 79 | + InstantiationException, IllegalAccessException { |
| 80 | + Class<?> formatterFunc = jarState.getClassLoader().loadClass("com.diffplug.spotless.glue.yaml.YamlJacksonFormatterFunc"); |
| 81 | + Constructor<?> constructor = formatterFunc.getConstructor(List.class, List.class); |
| 82 | + return (FormatterFunc) constructor.newInstance(enabledFeatures, disabledFeatures); |
141 | 83 | }
|
142 |
| - |
143 |
| - private String format(Object objectMapper, Method stringToNode, Method nodeToString, String s) |
144 |
| - throws IllegalAccessException, IllegalArgumentException { |
145 |
| - try { |
146 |
| - Object node = stringToNode.invoke(objectMapper, s); |
147 |
| - return (String) nodeToString.invoke(node); |
148 |
| - } catch (InvocationTargetException ex) { |
149 |
| - throw new AssertionError("Unable to format YAML", ex.getCause()); |
150 |
| - } |
151 |
| - } |
152 |
| - } |
153 |
| - |
154 |
| - private YamlJacksonStep() { |
155 |
| - // cannot be directly instantiated |
156 | 84 | }
|
157 | 85 | }
|
0 commit comments