2525import co .elastic .clients .elasticsearch .security .IndicesPrivileges ;
2626import co .elastic .clients .elasticsearch .security .RoleTemplateScript ;
2727import co .elastic .clients .elasticsearch .security .UserIndicesPrivileges ;
28- import co .elastic .clients .json .JsonpUtils ;
2928import co .elastic .clients .util .AllowForbiddenApis ;
3029import jakarta .json .JsonException ;
3130import jakarta .json .spi .JsonProvider ;
3231import jakarta .json .stream .JsonGenerator ;
32+ import jakarta .json .stream .JsonParser ;
3333import org .junit .jupiter .api .Test ;
3434
35+ import java .io .StringReader ;
3536import java .io .StringWriter ;
3637import java .net .URL ;
3738import java .util .Collections ;
@@ -209,6 +210,47 @@ public void testJsonString() {
209210 }
210211 }
211212
213+ @ Test
214+ public void testCopy () {
215+ // Tests round-tripping a json document that contains all event types and various kinds of nesting
216+
217+ String json = "{\n " +
218+ " \" p1\" : \" str1\" ,\n " +
219+ " \" p2\" : 42,\n " +
220+ " \" p3\" : [\" str31\" , \" str32\" ],\n " +
221+ " \" p4\" : {\n " +
222+ " \" p41\" : \" str41\" ,\n " +
223+ " \" p42\" : [\" str421\" , \" str422\" ],\n " +
224+ " \" p43\" : {\n " +
225+ " \" p431\" : \" str431\" \n " +
226+ " },\n " +
227+ " \" p44\" : true,\n " +
228+ " \" p45\" : false,\n " +
229+ " \" p46\" : 3.14\n " +
230+ " },\n " +
231+ " \" p5\" : [{\n " +
232+ " \" p51\" : {\n " +
233+ " \" p511\" : \" str511\" \n " +
234+ " }\n " +
235+ " }],\n " +
236+ " \" p6\" : null\n " +
237+ "}\n " ;
238+
239+ json = normalizeIndent (json );
240+
241+ JsonProvider provider = JsonpUtils .provider ();
242+
243+ JsonParser parser = provider .createParser (new StringReader (json ));
244+ StringWriter sw = new StringWriter ();
245+ JsonGenerator generator = provider .createGenerator (sw );
246+
247+ JsonpUtils .copy (parser , generator );
248+ parser .close ();
249+ generator .close ();
250+
251+ assertEquals (json , sw .toString ());
252+ }
253+
212254 private static String orNullHelper (Consumer <JsonGenerator > c ) {
213255 StringWriter sw = new StringWriter ();
214256 JsonGenerator generator = JsonpUtils .provider ().createGenerator (sw );
@@ -221,4 +263,69 @@ private static String orNullHelper(Consumer<JsonGenerator> c) {
221263
222264 return sw .toString ();
223265 }
266+
267+ /**
268+ * Normalizes the whitespace and indentation of a JSON string by parsing it and copying it to a string generator.
269+ */
270+ private static String normalizeIndent (String json ) {
271+ JsonParser parser = JsonpUtils .provider ().createParser (new StringReader (json ));
272+ StringWriter sw = new StringWriter ();
273+ JsonGenerator generator = JsonpUtils .provider ().createGenerator (sw );
274+
275+ copyAll (parser , generator );
276+
277+ parser .close ();
278+ generator .close ();
279+ return sw .toString ();
280+ }
281+
282+ private static void copyAll (JsonParser parser , JsonGenerator generator ) {
283+ while (parser .hasNext ()) {
284+ switch (parser .next ()) {
285+ case START_OBJECT :
286+ generator .writeStartObject ();
287+ break ;
288+
289+ case END_OBJECT :
290+ generator .writeEnd ();
291+ break ;
292+
293+ case START_ARRAY :
294+ generator .writeStartArray ();
295+ break ;
296+
297+ case END_ARRAY :
298+ generator .writeEnd ();
299+ break ;
300+
301+ case KEY_NAME :
302+ generator .writeKey (parser .getString ());
303+ break ;
304+
305+ case VALUE_STRING :
306+ generator .write (parser .getString ());
307+ break ;
308+
309+ case VALUE_NULL :
310+ generator .writeNull ();
311+ break ;
312+
313+ case VALUE_TRUE :
314+ generator .write (true );
315+ break ;
316+
317+ case VALUE_FALSE :
318+ generator .write (false );
319+ break ;
320+
321+ case VALUE_NUMBER :
322+ if (parser .isIntegralNumber ()) {
323+ generator .write (parser .getLong ());
324+ } else {
325+ generator .write (parser .getBigDecimal ());
326+ }
327+ break ;
328+ }
329+ }
330+ }
224331}
0 commit comments