1+ /**
2+ * Copyright 2023 Zhang Guanhu
3+ * <p>
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ * <p>
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ * <p>
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ package com .github .artbits .jsqlite ;
18+
19+ import java .lang .reflect .Field ;
20+ import java .math .BigDecimal ;
21+ import java .math .BigInteger ;
22+ import java .util .*;
23+
24+ final class JsonObject {
25+
26+ private final Map <String , String > map = new LinkedHashMap <>();
27+
28+
29+ <T > JsonObject (T t ) {
30+ beanToMap (t );
31+ }
32+
33+
34+ private <T > void beanToMap (T t ) {
35+ try {
36+ map .put ("\" id\" " , null );
37+ Class <?> clazz = t .getClass ();
38+ while (clazz != null ) {
39+ for (Field field : clazz .getDeclaredFields ()) {
40+ field .setAccessible (true );
41+ putMap (field .getName (), field .get (t ));
42+ }
43+ clazz = clazz .getSuperclass ();
44+ }
45+ } catch (IllegalAccessException e ) {
46+ throw new RuntimeException (e );
47+ }
48+ }
49+
50+
51+ private void putMap (String fieldName , Object fieldValue ) {
52+ if (fieldName == null || fieldValue == null || fieldValue instanceof Enum <?>) {
53+ return ;
54+ } else {
55+ fieldName = "\" " + fieldName + "\" " ;
56+ }
57+
58+ if (fieldValue instanceof String || fieldValue instanceof Character ) {
59+ if (!"\u0000 " .equals (String .valueOf (fieldValue ))) {
60+ map .put (fieldName , "\" " + fieldValue + "\" " );
61+ }
62+ return ;
63+ }
64+ if (fieldValue instanceof Byte || fieldValue instanceof Short
65+ || fieldValue instanceof Integer || fieldValue instanceof Long
66+ || fieldValue instanceof Boolean || fieldValue instanceof Float
67+ || fieldValue instanceof Double || fieldValue instanceof BigInteger
68+ || fieldValue instanceof BigDecimal ) {
69+ map .put (fieldName , String .valueOf (fieldValue ));
70+ return ;
71+ }
72+ if (fieldValue .getClass ().isArray ()) {
73+ map .put (fieldName , arrayToJSONString (fieldValue ));
74+ return ;
75+ }
76+ if (fieldValue instanceof Collection <?>) {
77+ map .put (fieldName , collectionToJSONString ((Collection <?>) fieldValue ));
78+ return ;
79+ }
80+ if (fieldValue instanceof Map <?, ?>) {
81+ map .put (fieldName , mapToJSONString ((Map <?, ?>) fieldValue ));
82+ return ;
83+ }
84+ map .put (fieldName , new JsonObject (fieldValue ).toString ());
85+ }
86+
87+
88+ @ Override
89+ public String toString () {
90+ StringBuilder builder = new StringBuilder ().append ("{" );
91+ map .forEach ((k , v ) -> Optional .ofNullable (v ).ifPresent (s -> builder .append (k ).append (":" ).append (v ).append ("," )));
92+ return builder .deleteCharAt (builder .length () - 1 ).append ("}" ).toString ();
93+ }
94+
95+
96+ private static String charArrayToJSONString (char [] chars ) {
97+ StringBuilder builder = new StringBuilder ();
98+ builder .append ("[" );
99+ for (char c : chars ) {
100+ builder .append ("\" " ).append (c ).append ("\" " ).append ("," );
101+ }
102+ return builder .deleteCharAt (builder .length () - 1 ).append ("]" ).toString ();
103+ }
104+
105+
106+ private static <T > String objectArrayToJSONString (T [] arrays ) {
107+ StringBuilder builder = new StringBuilder ();
108+ builder .append ("[" );
109+ for (Object o : arrays ) {
110+ ifTextType (o , () -> {
111+ builder .append ("\" " ).append (o ).append ("\" " ).append ("," );
112+ }, () -> {
113+ builder .append (new JsonObject (o )).append ("," );
114+ });
115+ }
116+ return builder .deleteCharAt (builder .length () - 1 ).append ("]" ).toString ();
117+ }
118+
119+
120+ private static String arrayToJSONString (Object object ) {
121+ if (object instanceof byte []) {
122+ return Arrays .toString ((byte []) object ).replaceAll (" " , "" );
123+ }
124+ if (object instanceof short []) {
125+ return Arrays .toString ((short []) object ).replaceAll (" " , "" );
126+ }
127+ if (object instanceof int []) {
128+ return Arrays .toString ((int []) object ).replaceAll (" " , "" );
129+ }
130+ if (object instanceof long []) {
131+ return Arrays .toString ((long []) object ).replaceAll (" " , "" );
132+ }
133+ if (object instanceof float []) {
134+ return Arrays .toString ((float []) object ).replaceAll (" " , "" );
135+ }
136+ if (object instanceof double []) {
137+ return Arrays .toString ((double []) object ).replaceAll (" " , "" );
138+ }
139+ if (object instanceof boolean []) {
140+ return Arrays .toString ((boolean []) object );
141+ }
142+ if (object instanceof char []) {
143+ return charArrayToJSONString ((char []) object );
144+ }
145+ if (object instanceof Object []) {
146+ return objectArrayToJSONString ((Object []) object );
147+ }
148+ return null ;
149+ }
150+
151+
152+ private static String collectionToJSONString (Collection <?> collection ) {
153+ StringBuilder builder = new StringBuilder ();
154+ builder .append ("[" );
155+ collection .forEach (o -> {
156+ ifBasicType (o , () -> {
157+ builder .append (o ).append ("," );
158+ }, () -> {
159+ ifTextType (o , () -> {
160+ builder .append ("\" " ).append (o ).append ("\" " ).append ("," );
161+ }, () -> {
162+ builder .append (new JsonObject (o )).append ("," );
163+ });
164+ });
165+ });
166+ return builder .deleteCharAt (builder .length () - 1 ).append ("]" ).toString ();
167+ }
168+
169+
170+ private static String mapToJSONString (Map <?, ?> map ) {
171+ StringBuilder builder = new StringBuilder ();
172+ builder .append ("{" );
173+ map .forEach ((k , v ) -> Optional .ofNullable ((k != null && v != null ) ? k : null ).ifPresent (o -> {
174+ builder .append ("\" " ).append (k ).append ("\" :" );
175+ ifBasicType (v , () -> {
176+ builder .append (v ).append ("," );
177+ }, () -> {
178+ ifTextType (v , () -> {
179+ builder .append ("\" " ).append (v ).append ("\" " ).append ("," );
180+ }, () -> {
181+ builder .append (new JsonObject (v )).append ("," );
182+ });
183+ });
184+ }));
185+ return builder .deleteCharAt (builder .length () - 1 ).append ("}" ).toString ();
186+ }
187+
188+
189+ private static void ifBasicType (Object o , Runnable runnable1 , Runnable runnable2 ) {
190+ if (o instanceof Byte || o instanceof Short || o instanceof Integer
191+ || o instanceof Long || o instanceof Boolean || o instanceof Float
192+ || o instanceof Double || o instanceof BigInteger || o instanceof BigDecimal ) {
193+ Optional .ofNullable (runnable1 ).ifPresent (Runnable ::run );
194+ } else {
195+ Optional .ofNullable (runnable2 ).ifPresent (Runnable ::run );
196+ }
197+ }
198+
199+
200+ private static void ifTextType (Object o , Runnable runnable1 , Runnable runnable2 ) {
201+ if (o instanceof String || o instanceof Character ) {
202+ Optional .ofNullable (runnable1 ).ifPresent (Runnable ::run );
203+ } else {
204+ Optional .ofNullable (runnable2 ).ifPresent (Runnable ::run );
205+ }
206+ }
207+
208+ }
0 commit comments