11package io .arex .inst .runtime .serializer ;
22
3+ import io .arex .agent .bootstrap .util .ArrayUtils ;
34import io .arex .agent .bootstrap .util .CollectionUtil ;
5+ import io .arex .agent .bootstrap .util .ReflectUtil ;
46import io .arex .agent .bootstrap .util .StringUtil ;
57import io .arex .inst .runtime .log .LogManager ;
68import io .arex .inst .runtime .util .TypeUtil ;
@@ -24,7 +26,6 @@ public static Builder builder(List<StringSerializable> serializableList) {
2426 }
2527
2628 public static final String EMPTY_LIST_JSON = "[]" ;
27- private static final String NESTED_LIST = "java.util.ArrayList-java.util.ArrayList" ;
2829 private static final String HASH_MAP_VALUES_CLASS = "java.util.HashMap$Values" ;
2930 private static final String ARRAY_LIST_CLASS = "java.util.ArrayList" ;
3031 public static final String SERIALIZE_SEPARATOR = "A@R#E$X" ;
@@ -40,20 +41,31 @@ public static String serializeWithException(Object object, String serializer) th
4041 return null ;
4142 }
4243
43- String typeName = TypeUtil .getName (object );
44- if (typeName .contains (NESTED_LIST )) {
45- StringBuilder jsonBuilder = new StringBuilder ();
46- List <List <?>> ans = (List <List <?>>) object ;
47- for (int i = 0 ; i < ans .size (); i ++) {
48- jsonBuilder .append (serializeWithException (ans .get (i ), serializer ));
49- if (i == ans .size () - 1 ) {
50- continue ;
51- }
44+ Collection <Collection <?>> nestedCollection = TypeUtil .toNestedCollection (object );
45+ if (nestedCollection != null ) {
46+ return serializeNestedCollection (serializer , nestedCollection );
47+ }
48+
49+ return INSTANCE .getSerializer (serializer ).serialize (object );
50+ }
51+
52+ private static String serializeNestedCollection (String serializer , Collection <Collection <?>> nestedCollection ) throws Throwable {
53+ StringBuilder jsonBuilder = new StringBuilder ();
54+ Iterator <Collection <?>> collectionIterator = nestedCollection .iterator ();
55+ while (collectionIterator .hasNext ()) {
56+ Collection <?> collection = collectionIterator .next ();
57+ if (collection == null ) {
58+ jsonBuilder .append (NULL_STRING );
59+ } else if (collection .isEmpty ()) {
60+ jsonBuilder .append (EMPTY_LIST_JSON );
61+ } else {
62+ jsonBuilder .append (serializeWithException (collection , serializer ));
63+ }
64+ if (collectionIterator .hasNext ()) {
5265 jsonBuilder .append (SERIALIZE_SEPARATOR );
5366 }
54- return jsonBuilder .toString ();
5567 }
56- return INSTANCE . getSerializer ( serializer ). serialize ( object );
68+ return jsonBuilder . toString ( );
5769 }
5870
5971 /**
@@ -78,10 +90,6 @@ public static String serialize(Object object, String serializer) {
7890 }
7991 }
8092
81- public static Serializer getINSTANCE () {
82- return INSTANCE ;
83- }
84-
8593 /**
8694 * Deserialize by Class
8795 *
@@ -133,12 +141,11 @@ public static <T> T deserialize(String value, Type type) {
133141 * @param typeName Complex type name, example: java.util.ArrayList-java.util.ArrayList,com.xxx.XXXType
134142 * @return T
135143 */
136- public static <T > T deserialize (String value , String typeName ) {
144+ public static <T > T deserialize (String value , String typeName , String serializer ) {
137145 if (StringUtil .isEmpty (value ) || StringUtil .isEmpty (typeName )) {
138146 return null ;
139147 }
140148
141- String serializer = null ;
142149 if (typeName .endsWith ("Exception" )) {
143150 serializer = "gson" ;
144151 }
@@ -147,43 +154,64 @@ public static <T> T deserialize(String value, String typeName) {
147154 return (T ) restoreHashMapValues (value , typeName , serializer );
148155 }
149156
150- if (!typeName .contains (NESTED_LIST )) {
151- return deserialize (value , TypeUtil .forName (typeName ), serializer );
157+ String [] typeNames = StringUtil .split (typeName , '-' );
158+ if (ArrayUtils .isNotEmpty (typeNames ) && TypeUtil .isCollection (typeNames [0 ])) {
159+ String [] innerTypeNames = StringUtil .split (typeNames [1 ], ',' );
160+ if (ArrayUtils .isNotEmpty (innerTypeNames ) && TypeUtil .isCollection (innerTypeNames [0 ])) {
161+ return (T ) deserializeNestedCollection (value , typeNames [0 ], innerTypeNames , serializer );
162+ }
152163 }
153164
154- try {
155- // Divide the json string according to the object separator added during serialization
156- String [] jsonList = StringUtil .splitByWholeSeparator (value , SERIALIZE_SEPARATOR );
157- List <List <?>> list = new ArrayList <>(jsonList .length );
165+ return deserialize (value , TypeUtil .forName (typeName ), serializer );
166+ }
158167
159- String innerElementClass = StringUtil .substring (typeName , NESTED_LIST .length () + 1 );
160- String [] innerElementClasses = StringUtil .split (innerElementClass , ',' );
168+ public static <T > T deserialize (String value , String typeName ) {
169+ return deserialize (value , typeName , null );
170+ }
161171
162- int elementIndex = 0 ;
163- for (String innerJson : jsonList ) {
164- if (EMPTY_LIST_JSON .equals (innerJson )) {
165- list .add (new ArrayList <>());
166- continue ;
167- }
172+ /**
173+ * Deserialize nested collection
174+ * @param json json string
175+ * @param collectionType type name eg: java.util.HashSet-java.util.HashSet,java.lang.String,java.lang.String
176+ * @param serializer serializer
177+ */
178+ private static <T > Collection <Collection <T >> deserializeNestedCollection (String json , String collectionType ,
179+ String [] innerCollectionType , String serializer ) {
180+ Collection <Collection <T >> collection = ReflectUtil .getCollectionInstance (collectionType );
181+ if (collection == null ) {
182+ return null ;
183+ }
168184
169- if (NULL_STRING .equals (innerJson )) {
170- list .add (null );
171- continue ;
172- }
185+ if (ArrayUtils .isEmpty (innerCollectionType )) {
186+ return collection ;
187+ }
173188
174- if (innerElementClasses != null && innerElementClasses .length > elementIndex ) {
175- // The intercepted value and TypeName are deserialized in one-to-one correspondence
176- String innerListTypeName = String .format ("java.util.ArrayList-%s" , innerElementClasses [elementIndex ]);
177- list .add (deserialize (innerJson , TypeUtil .forName (innerListTypeName ), serializer ));
178- elementIndex ++;
179- }
189+ // Divide the json string according to the object separator added during serialization
190+ String [] jsonArray = StringUtil .splitByWholeSeparator (json , SERIALIZE_SEPARATOR );
191+
192+ int elementIndex = 1 ;
193+ StringBuilder builder = new StringBuilder ();
194+ for (String innerJson : jsonArray ) {
195+ if (EMPTY_LIST_JSON .equals (innerJson )) {
196+ collection .add (ReflectUtil .getCollectionInstance (innerCollectionType [0 ]));
197+ continue ;
180198 }
181199
182- return (T ) list ;
183- } catch (Throwable ex ) {
184- LogManager .warn ("serializer-deserialize-typeName" , StringUtil .format ("can not deserialize value %s to class %s, cause: %s" , value , typeName , ex .toString ()));
185- return null ;
200+ if (StringUtil .isNullWord (innerJson )) {
201+ collection .add (null );
202+ continue ;
203+ }
204+
205+ if (innerCollectionType .length > elementIndex ) {
206+ // The intercepted value and TypeName are deserialized in one-to-one correspondence
207+ builder .append (innerCollectionType [0 ]).append ('-' ).append (innerCollectionType [elementIndex ]);
208+ collection .add (deserialize (innerJson , TypeUtil .forName (builder .toString ()), serializer ));
209+ builder .setLength (0 );
210+ elementIndex ++;
211+ }
186212 }
213+
214+ return collection ;
187215 }
188216
189217 private static Collection <?> restoreHashMapValues (String value , String typeName , String serializer ) {
@@ -201,6 +229,10 @@ private static Collection<?> restoreHashMapValues(String value, String typeName,
201229 return map .values ();
202230 }
203231
232+ public static Serializer getINSTANCE () {
233+ return INSTANCE ;
234+ }
235+
204236 public Map <String , StringSerializable > getSerializers () {
205237 return serializers ;
206238 }
0 commit comments