• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wuwen5 / hessian / 17023334512

17 Aug 2025 04:22PM UTC coverage: 43.93% (-0.2%) from 44.094%
17023334512

push

github

wuwen5
refactor: code clean,fix sonar java:S1117 and other.

1202 of 2983 branches covered (40.3%)

Branch coverage included in aggregate %.

2865 of 6275 relevant lines covered (45.66%)

1.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.53
hessian2-codec/src/main/java/io/github/wuwen5/hessian/io/JavaSerializer.java
1
/*
2
 * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
3
 *
4
 * The Apache Software License, Version 1.1
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in
15
 *    the documentation and/or other materials provided with the
16
 *    distribution.
17
 *
18
 * 3. The end-user documentation included with the redistribution, if
19
 *    any, must include the following acknowlegement:
20
 *       "This product includes software developed by the
21
 *        Caucho Technology (http://www.caucho.com/)."
22
 *    Alternately, this acknowlegement may appear in the software itself,
23
 *    if and wherever such third-party acknowlegements normally appear.
24
 *
25
 * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
26
 *    endorse or promote products derived from this software without prior
27
 *    written permission. For written permission, please contact
28
 *    info@caucho.com.
29
 *
30
 * 5. Products derived from this software may not be called "Resin"
31
 *    nor may "Resin" appear in their names without prior written
32
 *    permission of Caucho Technology.
33
 *
34
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37
 * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
 *
46
 * @author Scott Ferguson
47
 */
48

49
package io.github.wuwen5.hessian.io;
50

51
import io.github.wuwen5.hessian.HessianUnshared;
52
import java.io.IOException;
53
import java.lang.ref.SoftReference;
54
import java.lang.reflect.Field;
55
import java.lang.reflect.Method;
56
import java.lang.reflect.Modifier;
57
import java.util.ArrayList;
58
import java.util.WeakHashMap;
59
import java.util.logging.Level;
60
import java.util.logging.Logger;
61

62
/**
63
 * Serializing an object for known object types.
64
 */
65
public class JavaSerializer extends AbstractSerializer {
66
    private static final Logger log = Logger.getLogger(JavaSerializer.class.getName());
4✔
67

68
    private static final WeakHashMap<Class<?>, SoftReference<JavaSerializer>> SERIALIZER_MAP = new WeakHashMap<>();
5✔
69

70
    private Field[] fields;
71
    private FieldSerializer[] fieldSerializers;
72

73
    private Object writeReplaceFactory;
74
    private final Method writeReplace;
75

76
    public JavaSerializer(Class<?> cl) {
2✔
77
        introspect(cl);
3✔
78

79
        writeReplace = getWriteReplace(cl);
4✔
80

81
        if (writeReplace != null) {
3!
82
            writeReplace.setAccessible(true);
4✔
83
        }
84
    }
1✔
85

86
    public static Serializer create(Class<?> cl) {
87
        synchronized (SERIALIZER_MAP) {
4✔
88
            SoftReference<JavaSerializer> baseRef = SERIALIZER_MAP.get(cl);
5✔
89

90
            JavaSerializer base = baseRef != null ? baseRef.get() : null;
4!
91

92
            if (base == null) {
2!
93
                if (cl.isAnnotationPresent(HessianUnshared.class)) {
4!
94
                    base = new JavaUnsharedSerializer(cl);
×
95
                } else {
96
                    base = new JavaSerializer(cl);
5✔
97
                }
98

99
                baseRef = new SoftReference<>(base);
5✔
100
                SERIALIZER_MAP.put(cl, baseRef);
5✔
101
            }
102

103
            return base;
4✔
104
        }
105
    }
106

107
    protected void introspect(Class<?> cl) {
108
        if (writeReplace != null) {
3!
109
            writeReplace.setAccessible(true);
×
110
        }
111

112
        ArrayList<Field> primitiveFields = new ArrayList<>();
4✔
113
        ArrayList<Field> compoundFields = new ArrayList<>();
4✔
114

115
        for (; cl != null; cl = cl.getSuperclass()) {
6✔
116
            for (Field field : cl.getDeclaredFields()) {
17✔
117
                if (Modifier.isTransient(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
8✔
118
                    continue;
1✔
119
                }
120

121
                // XXX: could parameterize the handler to only deal with public
122
                field.setAccessible(true);
3✔
123

124
                if (field.getType().isPrimitive()
5✔
125
                        || (field.getType().getName().startsWith("java.lang.")
6✔
126
                                && !field.getType().equals(Object.class))) {
4✔
127
                    primitiveFields.add(field);
5✔
128
                } else {
129
                    compoundFields.add(field);
4✔
130
                }
131
            }
132
        }
133

134
        ArrayList<Field> fieldArrayList = new ArrayList<>();
4✔
135
        fieldArrayList.addAll(primitiveFields);
4✔
136
        fieldArrayList.addAll(compoundFields);
4✔
137

138
        this.fields = new Field[fieldArrayList.size()];
5✔
139
        fieldArrayList.toArray(this.fields);
5✔
140

141
        fieldSerializers = new FieldSerializer[this.fields.length];
6✔
142

143
        for (int i = 0; i < this.fields.length; i++) {
9✔
144
            fieldSerializers[i] = getFieldSerializer(this.fields[i].getType());
10✔
145
        }
146
    }
1✔
147

148
    /**
149
     * Returns the writeReplace method
150
     */
151
    protected static Method getWriteReplace(Class<?> cl) {
152
        for (; cl != null; cl = cl.getSuperclass()) {
6✔
153
            Method[] methods = cl.getDeclaredMethods();
3✔
154

155
            for (Method method : methods) {
16✔
156
                if ("writeReplace".equals(method.getName()) && method.getParameterTypes().length == 0) {
9!
157
                    return method;
2✔
158
                }
159
            }
160
        }
161

162
        return null;
2✔
163
    }
164

165
    /**
166
     * Returns the writeReplace method
167
     */
168
    protected Method getWriteReplace(Class<?> cl, Class<?> param) {
169
        for (; cl != null; cl = cl.getSuperclass()) {
×
170
            for (Method method : cl.getDeclaredMethods()) {
×
171
                if ("writeReplace".equals(method.getName())
×
172
                        && method.getParameterTypes().length == 1
×
173
                        && param.equals(method.getParameterTypes()[0])) {
×
174
                    return method;
×
175
                }
176
            }
177
        }
178

179
        return null;
×
180
    }
181

182
    @Override
183
    public void writeObject(Object obj, AbstractHessianEncoder out) throws IOException {
184
        if (out.addRef(obj)) {
4!
185
            return;
×
186
        }
187

188
        Class<?> cl = obj.getClass();
3✔
189

190
        try {
191
            if (writeReplace != null) {
3!
192
                Object repl;
193

194
                if (writeReplaceFactory != null) {
3!
195
                    repl = writeReplace.invoke(writeReplaceFactory, obj);
×
196
                } else {
197
                    repl = writeReplace.invoke(obj);
7✔
198
                }
199

200
                // hessian/3a5a
201
                int ref = out.writeObjectBegin(cl.getName());
5✔
202

203
                if (ref < -1) {
3!
204
                    writeObject10(repl, out);
×
205
                } else {
206
                    if (ref == -1) {
3!
207
                        writeDefinition20(out);
3✔
208
                        out.writeObjectBegin(cl.getName());
5✔
209
                    }
210

211
                    writeInstance(repl, out);
4✔
212
                }
213

214
                return;
1✔
215
            }
216
        } catch (RuntimeException e) {
×
217
            throw e;
×
218
        } catch (Exception e) {
×
219
            throw new RuntimeException(e);
×
220
        }
×
221

222
        int ref = out.writeObjectBegin(cl.getName());
×
223

224
        if (ref < -1) {
×
225
            writeObject10(obj, out);
×
226
        } else {
227
            if (ref == -1) {
×
228
                writeDefinition20(out);
×
229
                out.writeObjectBegin(cl.getName());
×
230
            }
231

232
            writeInstance(obj, out);
×
233
        }
234
    }
×
235

236
    @Override
237
    protected void writeObject10(Object obj, AbstractHessianEncoder out) throws IOException {
238
        for (int i = 0; i < fields.length; i++) {
×
239
            Field field = fields[i];
×
240

241
            out.writeString(field.getName());
×
242

243
            fieldSerializers[i].serialize(out, obj, field);
×
244
        }
245

246
        out.writeMapEnd();
×
247
    }
×
248

249
    private void writeDefinition20(AbstractHessianEncoder out) throws IOException {
250
        out.writeClassFieldLength(fields.length);
5✔
251

252
        for (Field field : fields) {
17✔
253
            out.writeString(field.getName());
4✔
254
        }
255
    }
1✔
256

257
    @Override
258
    public void writeInstance(Object obj, AbstractHessianEncoder out) throws IOException {
259
        try {
260
            for (int i = 0; i < fields.length; i++) {
9✔
261
                Field field = fields[i];
5✔
262

263
                fieldSerializers[i].serialize(out, obj, field);
8✔
264
            }
265
        } catch (RuntimeException e) {
×
266
            throw new RuntimeException(
×
267
                    e.getMessage() + "\n class: " + obj.getClass().getName() + " (object=" + obj + ")", e);
×
268
        } catch (IOException e) {
×
269
            throw new IOExceptionWrapper(
×
270
                    e.getMessage() + "\n class: " + obj.getClass().getName() + " (object=" + obj + ")", e);
×
271
        }
1✔
272
    }
1✔
273

274
    private static FieldSerializer getFieldSerializer(Class<?> type) {
275
        if (int.class.equals(type) || byte.class.equals(type) || short.class.equals(type)) {
12!
276
            return IntFieldSerializer.SER;
2✔
277
        } else if (long.class.equals(type)) {
4✔
278
            return LongFieldSerializer.SER;
2✔
279
        } else if (double.class.equals(type) || float.class.equals(type)) {
8!
280
            return DoubleFieldSerializer.SER;
×
281
        } else if (boolean.class.equals(type)) {
4!
282
            return BooleanFieldSerializer.SER;
×
283
        } else if (String.class.equals(type)) {
4✔
284
            return StringFieldSerializer.SER;
2✔
285
        } else if (java.util.Date.class.equals(type)
6!
286
                || java.sql.Date.class.equals(type)
4!
287
                || java.sql.Timestamp.class.equals(type)
4!
288
                || java.sql.Time.class.equals(type)) {
2!
289
            return DateFieldSerializer.SER;
×
290
        } else {
291
            return FieldSerializer.SER;
2✔
292
        }
293
    }
294

295
    static class FieldSerializer {
3✔
296
        static final FieldSerializer SER = new FieldSerializer();
5✔
297

298
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
299
            Object value = null;
×
300

301
            try {
302
                value = field.get(obj);
×
303
            } catch (IllegalAccessException e) {
×
304
                log.log(Level.FINE, e.toString(), e);
×
305
            }
×
306

307
            try {
308
                out.writeObject(value);
×
309
            } catch (RuntimeException e) {
×
310
                throw new RuntimeException(
×
311
                        e.getMessage() + "\n field: "
×
312
                                + field.getDeclaringClass().getName()
×
313
                                + '.' + field.getName(),
×
314
                        e);
315
            } catch (IOException e) {
×
316
                throw new IOExceptionWrapper(
×
317
                        e.getMessage() + "\n field: "
×
318
                                + field.getDeclaringClass().getName()
×
319
                                + '.' + field.getName(),
×
320
                        e);
321
            }
×
322
        }
×
323
    }
324

325
    static class BooleanFieldSerializer extends FieldSerializer {
×
326
        static final FieldSerializer SER = new BooleanFieldSerializer();
×
327

328
        @Override
329
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
330
            boolean value = false;
×
331

332
            try {
333
                value = field.getBoolean(obj);
×
334
            } catch (IllegalAccessException e) {
×
335
                log.log(Level.FINE, e.toString(), e);
×
336
            }
×
337

338
            out.writeBoolean(value);
×
339
        }
×
340
    }
341

342
    static class IntFieldSerializer extends FieldSerializer {
3✔
343
        static final FieldSerializer SER = new IntFieldSerializer();
5✔
344

345
        @Override
346
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
347
            int value = 0;
×
348

349
            try {
350
                value = field.getInt(obj);
×
351
            } catch (IllegalAccessException e) {
×
352
                log.log(Level.FINE, e.toString(), e);
×
353
            }
×
354

355
            out.writeInt(value);
×
356
        }
×
357
    }
358

359
    static class LongFieldSerializer extends FieldSerializer {
3✔
360
        static final FieldSerializer SER = new LongFieldSerializer();
5✔
361

362
        @Override
363
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
364
            long value = 0;
×
365

366
            try {
367
                value = field.getLong(obj);
×
368
            } catch (IllegalAccessException e) {
×
369
                log.log(Level.FINE, e.toString(), e);
×
370
            }
×
371

372
            out.writeLong(value);
×
373
        }
×
374
    }
375

376
    static class DoubleFieldSerializer extends FieldSerializer {
×
377
        static final FieldSerializer SER = new DoubleFieldSerializer();
×
378

379
        @Override
380
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
381
            double value = 0;
×
382

383
            try {
384
                value = field.getDouble(obj);
×
385
            } catch (IllegalAccessException e) {
×
386
                log.log(Level.FINE, e.toString(), e);
×
387
            }
×
388

389
            out.writeDouble(value);
×
390
        }
×
391
    }
392

393
    static class StringFieldSerializer extends FieldSerializer {
3✔
394
        static final FieldSerializer SER = new StringFieldSerializer();
5✔
395

396
        @Override
397
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
398
            String value = null;
2✔
399

400
            try {
401
                value = (String) field.get(obj);
5✔
402
            } catch (IllegalAccessException e) {
×
403
                log.log(Level.FINE, e.toString(), e);
×
404
            }
1✔
405

406
            out.writeString(value);
3✔
407
        }
1✔
408
    }
409

410
    static class DateFieldSerializer extends FieldSerializer {
×
411
        static final FieldSerializer SER = new DateFieldSerializer();
×
412

413
        @Override
414
        void serialize(AbstractHessianEncoder out, Object obj, Field field) throws IOException {
415
            java.util.Date value = null;
×
416

417
            try {
418
                value = (java.util.Date) field.get(obj);
×
419
            } catch (IllegalAccessException e) {
×
420
                log.log(Level.FINE, e.toString(), e);
×
421
            }
×
422

423
            if (value == null) {
×
424
                out.writeNull();
×
425
            } else {
426
                out.writeUTCDate(value.getTime());
×
427
            }
428
        }
×
429
    }
430
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc