1
1
package com .arangodb .internal .serde ;
2
2
3
+ import com .arangodb .internal .ShadedProxy ;
3
4
import org .slf4j .Logger ;
4
5
import org .slf4j .LoggerFactory ;
5
6
6
- import java .lang .reflect .Method ;
7
- import java .util .ArrayList ;
8
- import java .util .List ;
9
-
10
7
public final class JacksonUtils {
11
8
private static final Logger LOG = LoggerFactory .getLogger (JacksonUtils .class );
12
9
13
10
private JacksonUtils () {
14
11
}
15
12
13
+ public interface Version {
14
+ int getMajorVersion ();
15
+
16
+ int getMinorVersion ();
17
+
18
+ String toString ();
19
+ }
20
+
21
+ public interface StreamReadConstraints {
22
+
23
+ interface Static {
24
+ Builder builder ();
25
+ }
26
+
27
+ interface Builder {
28
+ Builder maxNumberLength (final int maxNumLen );
29
+
30
+ Builder maxStringLength (int maxStringLen );
31
+
32
+ Builder maxNestingDepth (int maxNestingDepth );
33
+
34
+ Builder maxNameLength (int maxNameLen );
35
+
36
+ Builder maxDocumentLength (long maxDocLen );
37
+
38
+ StreamReadConstraints build ();
39
+ }
40
+ }
41
+
42
+ public interface StreamWriteConstraints {
43
+ interface Static {
44
+ Builder builder ();
45
+ }
46
+
47
+ interface Builder {
48
+ Builder maxNestingDepth (int maxNestingDepth );
49
+
50
+ StreamWriteConstraints build ();
51
+ }
52
+ }
53
+
54
+ public interface JsonFactory {
55
+ Version version ();
56
+
57
+ @ SuppressWarnings ("UnusedReturnValue" )
58
+ JsonFactory setStreamReadConstraints (StreamReadConstraints src );
59
+
60
+ @ SuppressWarnings ("UnusedReturnValue" )
61
+ JsonFactory setStreamWriteConstraints (StreamWriteConstraints swc );
62
+ }
63
+
16
64
/**
17
65
* Configure JsonFactory with permissive StreamReadConstraints and StreamWriteConstraints.
18
66
* It uses reflection to avoid compilation errors with older Jackson versions.
@@ -29,74 +77,51 @@ public static void tryConfigureJsonFactory(Object jf) {
29
77
}
30
78
31
79
private static void configureJsonFactory (Object jf ) throws Exception {
32
- // using reflection because these configuration are not supported in older Jackson versions
33
- if (isAtLeastVersion (jf , 2 , 15 )) {
34
- LOG .debug ("Configuring StreamReadConstraints ..." );
35
- List <Invocation > readConf = new ArrayList <>();
36
- readConf .add (new Invocation ("maxNumberLength" , int .class , Integer .MAX_VALUE ));
37
- readConf .add (new Invocation ("maxStringLength" , int .class , Integer .MAX_VALUE ));
38
- readConf .add (new Invocation ("maxNestingDepth" , int .class , Integer .MAX_VALUE ));
39
- if (isAtLeastVersion (jf , 2 , 16 )) {
40
- readConf .add (new Invocation ("maxNameLength" , int .class , Integer .MAX_VALUE ));
41
- readConf .add (new Invocation ("maxDocumentLength" , long .class , Long .MAX_VALUE ));
80
+ JsonFactory proxy = ShadedProxy .of (JsonFactory .class , jf );
81
+ Version version = proxy .version ();
82
+ LOG .debug ("Detected Jackson version: {}" , version );
83
+
84
+ // get pkg name dynamically, to support shaded Jackson
85
+ String basePkg = jf .getClass ().getPackage ().getName ();
86
+
87
+ if (isAtLeastVersion (version , 2 , 15 )) {
88
+ Class <?> srcClass = Class .forName (basePkg + "." + StreamReadConstraints .class .getSimpleName ());
89
+ StreamReadConstraints .Builder builder = ShadedProxy .of (StreamReadConstraints .Static .class , srcClass )
90
+ .builder ()
91
+ .maxNumberLength (Integer .MAX_VALUE )
92
+ .maxStringLength (Integer .MAX_VALUE )
93
+ .maxNestingDepth (Integer .MAX_VALUE );
94
+ if (isAtLeastVersion (version , 2 , 16 )) {
95
+ builder = builder
96
+ .maxNameLength (Integer .MAX_VALUE )
97
+ .maxDocumentLength (Long .MAX_VALUE );
42
98
} else {
43
99
LOG .debug ("Skipping configuring StreamReadConstraints maxNameLength" );
44
100
LOG .debug ("Skipping configuring StreamReadConstraints maxDocumentLength" );
45
101
}
46
- configureStreamConstraints ( jf , "StreamReadConstraints" , readConf );
102
+ proxy . setStreamReadConstraints ( builder . build () );
47
103
} else {
48
104
LOG .debug ("Skipping configuring StreamReadConstraints" );
49
105
}
50
106
51
- if (isAtLeastVersion (jf , 2 , 16 )) {
107
+ if (isAtLeastVersion (version , 2 , 16 )) {
52
108
LOG .debug ("Configuring StreamWriteConstraints ..." );
53
- List <Invocation > writeConf = new ArrayList <>();
54
- writeConf .add (new Invocation ("maxNestingDepth" , int .class , Integer .MAX_VALUE ));
55
- configureStreamConstraints (jf , "StreamWriteConstraints" , writeConf );
109
+ Class <?> swcClass = Class .forName (basePkg + "." + StreamWriteConstraints .class .getSimpleName ());
110
+ StreamWriteConstraints swc = ShadedProxy .of (StreamWriteConstraints .Static .class , swcClass )
111
+ .builder ()
112
+ .maxNestingDepth (Integer .MAX_VALUE )
113
+ .build ();
114
+ proxy .setStreamWriteConstraints (swc );
56
115
} else {
57
116
LOG .debug ("Skipping configuring StreamWriteConstraints" );
58
117
}
59
118
}
60
119
61
- private static boolean isAtLeastVersion (Object jf , int major , int minor ) throws Exception {
62
- Class <?> packageVersionClass = Class .forName (jf .getClass ().getPackage ().getName () + ".json.PackageVersion" );
63
- Object version = packageVersionClass .getDeclaredField ("VERSION" ).get (null );
64
-
65
- Class <?> versionClass = Class .forName (jf .getClass ().getPackage ().getName () + ".Version" );
66
- int currentMajor = (int ) versionClass .getDeclaredMethod ("getMajorVersion" ).invoke (version );
67
- int currentMinor = (int ) versionClass .getDeclaredMethod ("getMinorVersion" ).invoke (version );
68
-
69
- LOG .debug ("Detected Jackson version: {}.{}" , currentMajor , currentMinor );
70
-
120
+ @ SuppressWarnings ("SameParameterValue" )
121
+ private static boolean isAtLeastVersion (Version version , int major , int minor ) {
122
+ int currentMajor = version .getMajorVersion ();
123
+ int currentMinor = version .getMinorVersion ();
71
124
return currentMajor > major || (currentMajor == major && currentMinor >= minor );
72
125
}
73
126
74
- private static void configureStreamConstraints (Object jf , String className , List <Invocation > conf ) throws Exception {
75
- // get pkg name dynamically, to support shaded Jackson
76
- String basePkg = jf .getClass ().getPackage ().getName ();
77
- Class <?> streamConstraintsClass = Class .forName (basePkg + "." + className );
78
- Class <?> builderClass = Class .forName (basePkg + "." + className + "$Builder" );
79
- Method buildMethod = builderClass .getDeclaredMethod ("build" );
80
- Method builderMethod = streamConstraintsClass .getDeclaredMethod ("builder" );
81
- Object builder = builderMethod .invoke (null );
82
- for (Invocation i : conf ) {
83
- Method method = builderClass .getDeclaredMethod (i .method , i .argType );
84
- method .invoke (builder , i .arg );
85
- }
86
- Object streamReadConstraints = buildMethod .invoke (builder );
87
- Method setStreamReadConstraintsMethod = jf .getClass ().getDeclaredMethod ("set" + className , streamConstraintsClass );
88
- setStreamReadConstraintsMethod .invoke (jf , streamReadConstraints );
89
- }
90
-
91
- private static class Invocation {
92
- final String method ;
93
- final Class <?> argType ;
94
- final Object arg ;
95
-
96
- Invocation (String method , Class <?> argType , Object arg ) {
97
- this .method = method ;
98
- this .argType = argType ;
99
- this .arg = arg ;
100
- }
101
- }
102
127
}
0 commit comments