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

wuwen5 / hessian / 17177490298

23 Aug 2025 03:42PM UTC coverage: 68.416% (+11.8%) from 56.631%
17177490298

push

github

web-flow
refactor: fix sonar S2184 and code clean (#29)

1781 of 2793 branches covered (63.77%)

Branch coverage included in aggregate %.

4152 of 5879 relevant lines covered (70.62%)

3.07 hits per line

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

80.08
hessian2-codec/src/main/java/io/github/wuwen5/hessian/io/JavaDeserializer.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 java.io.IOException;
52
import java.lang.reflect.Constructor;
53
import java.lang.reflect.Field;
54
import java.lang.reflect.InvocationTargetException;
55
import java.lang.reflect.Method;
56
import java.lang.reflect.Modifier;
57
import java.util.HashMap;
58

59
/**
60
 * Serializing an object for known object types.
61
 */
62
public class JavaDeserializer extends AbstractMapDeserializer {
63
    private final Class<?> type;
64
    private final HashMap<?, FieldDeserializer2> fieldMap;
65
    private final Method readResolve;
66
    private final Constructor<?> constructor;
67
    private final Object[] constructorArgs;
68

69
    public JavaDeserializer(Class<?> cl, FieldDeserializer2Factory fieldFactory) {
2✔
70
        type = cl;
3✔
71
        fieldMap = getFieldMap(cl, fieldFactory);
6✔
72

73
        readResolve = getReadResolve(cl);
5✔
74

75
        if (readResolve != null) {
3✔
76
            readResolve.setAccessible(true);
4✔
77
        }
78

79
        constructor = getConstructor(cl);
5✔
80
        constructorArgs = getConstructorArgs(constructor);
6✔
81
    }
1✔
82

83
    protected Constructor<?> getConstructor(Class<?> cl) {
84
        Constructor<?>[] constructors = cl.getDeclaredConstructors();
3✔
85
        long bestCost = Long.MAX_VALUE;
2✔
86

87
        Constructor<?> constructorVar = null;
2✔
88

89
        for (Constructor<?> value : constructors) {
16✔
90
            Class<?>[] param = value.getParameterTypes();
3✔
91
            long cost = getCost(param);
3✔
92

93
            if (cost < bestCost) {
4✔
94
                constructorVar = value;
2✔
95
                bestCost = cost;
2✔
96
            }
97
        }
98

99
        if (constructorVar != null) {
2✔
100
            constructorVar.setAccessible(true);
3✔
101
        }
102

103
        return constructorVar;
2✔
104
    }
105

106
    private static long getCost(Class<?>[] param) {
107
        long cost = 0;
2✔
108

109
        for (Class<?> aClass : param) {
16✔
110
            cost = 4 * cost;
4✔
111

112
            if (Object.class.equals(aClass)) {
4!
113
                cost += 1;
×
114
            } else if (String.class.equals(aClass)) {
4✔
115
                cost += 2;
5✔
116
            } else if (int.class.equals(aClass)) {
4✔
117
                cost += 3;
5✔
118
            } else if (long.class.equals(aClass)) {
4✔
119
                cost += 4;
5✔
120
            } else if (aClass.isPrimitive()) {
3✔
121
                cost += 5;
5✔
122
            } else {
123
                cost += 6;
4✔
124
            }
125
        }
126

127
        if (cost < 0 || cost > (1L << 48)) {
8!
128
            cost = 1L << 48;
×
129
        }
130

131
        cost += (long) param.length << 48;
8✔
132
        return cost;
2✔
133
    }
134

135
    protected Object[] getConstructorArgs(Constructor<?> constructor) {
136
        Object[] objects = null;
2✔
137

138
        if (constructor != null) {
2✔
139
            Class<?>[] params = constructor.getParameterTypes();
3✔
140
            objects = new Object[params.length];
4✔
141
            for (int i = 0; i < params.length; i++) {
8✔
142
                objects[i] = getParamArg(params[i]);
7✔
143
            }
144
        }
145

146
        return objects;
2✔
147
    }
148

149
    @Override
150
    public Class<?> getType() {
151
        return type;
3✔
152
    }
153

154
    @Override
155
    public boolean isReadResolve() {
156
        return readResolve != null;
6!
157
    }
158

159
    @Override
160
    public Object readMap(AbstractHessianDecoder in) throws IOException {
161
        try {
162
            Object obj = instantiate();
3✔
163

164
            return readMap(in, obj);
5✔
165
        } catch (IOException | RuntimeException e) {
1✔
166
            throw e;
2✔
167
        } catch (Exception e) {
×
168
            throw new IOExceptionWrapper(type.getName() + ":" + e.getMessage(), e);
×
169
        }
170
    }
171

172
    @Override
173
    public Object[] createFields(int len) {
174
        return new FieldDeserializer2[len];
3✔
175
    }
176

177
    @Override
178
    public Object createField(String name) {
179
        Object reader = fieldMap.get(name);
5✔
180

181
        if (reader == null) {
2!
182
            reader = FieldDeserializer2Factory.NullFieldDeserializer.DESER;
×
183
        }
184

185
        return reader;
2✔
186
    }
187

188
    @Override
189
    public Object readObject(AbstractHessianDecoder in, Object[] fields) throws IOException {
190
        try {
191
            Object obj = instantiate();
3✔
192

193
            return readObject(in, obj, (FieldDeserializer2[]) fields);
7✔
194
        } catch (IOException | RuntimeException e) {
×
195
            throw e;
×
196
        } catch (Exception e) {
×
197
            throw new IOExceptionWrapper(type.getName() + ":" + e.getMessage(), e);
×
198
        }
199
    }
200

201
    @Override
202
    public Object readObject(AbstractHessianDecoder in, String[] fieldNames) throws IOException {
203
        try {
204
            Object obj = instantiate();
3✔
205

206
            return readObject(in, obj, fieldNames);
6✔
207
        } catch (IOException | RuntimeException e) {
×
208
            throw e;
×
209
        } catch (Exception e) {
×
210
            throw new IOExceptionWrapper(type.getName() + ":" + e.getMessage(), e);
×
211
        }
212
    }
213

214
    /**
215
     * Returns the readResolve method
216
     */
217
    protected Method getReadResolve(Class<?> cl) {
218
        for (; cl != null; cl = cl.getSuperclass()) {
6✔
219
            Method[] methods = cl.getDeclaredMethods();
3✔
220

221
            for (Method method : methods) {
16✔
222
                if ("readResolve".equals(method.getName()) && method.getParameterTypes().length == 0) {
9!
223
                    return method;
2✔
224
                }
225
            }
226
        }
227

228
        return null;
2✔
229
    }
230

231
    public Object readMap(AbstractHessianDecoder in, Object obj) throws IOException {
232
        try {
233
            int ref = in.addRef(obj);
4✔
234

235
            while (!in.isEnd()) {
3✔
236
                Object key = in.readObject();
3✔
237

238
                FieldDeserializer2 deser = fieldMap.get(key);
6✔
239

240
                if (deser != null) {
2!
241
                    deser.deserialize(in, obj);
5✔
242
                } else {
243
                    in.readObject();
×
244
                }
245
            }
1✔
246

247
            in.readMapEnd();
2✔
248

249
            Object resolve = resolve(in, obj);
5✔
250

251
            if (obj != resolve) {
3!
252
                in.setRef(ref, resolve);
×
253
            }
254

255
            return resolve;
2✔
256
        } catch (IOException e) {
×
257
            throw e;
×
258
        } catch (Exception e) {
×
259
            throw new IOExceptionWrapper(e);
×
260
        }
261
    }
262

263
    private Object readObject(AbstractHessianDecoder in, Object obj, FieldDeserializer2[] fields) throws IOException {
264
        try {
265
            int ref = in.addRef(obj);
4✔
266

267
            for (FieldDeserializer2 reader : fields) {
16✔
268
                reader.deserialize(in, obj);
4✔
269
            }
270

271
            Object resolve = resolve(in, obj);
5✔
272

273
            if (obj != resolve) {
3!
274
                in.setRef(ref, resolve);
×
275
            }
276

277
            return resolve;
2✔
278
        } catch (IOException e) {
×
279
            throw e;
×
280
        } catch (Exception e) {
×
281
            throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e);
×
282
        }
283
    }
284

285
    public Object readObject(AbstractHessianDecoder in, Object obj, String[] fieldNames) throws IOException {
286
        try {
287
            int ref = in.addRef(obj);
4✔
288

289
            for (String fieldName : fieldNames) {
16✔
290
                FieldDeserializer2 reader = fieldMap.get(fieldName);
6✔
291

292
                if (reader != null) {
2!
293
                    reader.deserialize(in, obj);
5✔
294
                } else {
295
                    in.readObject();
×
296
                }
297
            }
298

299
            Object resolve = resolve(in, obj);
5✔
300

301
            if (obj != resolve) {
3!
302
                in.setRef(ref, resolve);
4✔
303
            }
304

305
            return resolve;
2✔
306
        } catch (IOException e) {
×
307
            throw e;
×
308
        } catch (Exception e) {
×
309
            throw new IOExceptionWrapper(obj.getClass().getName() + ":" + e, e);
×
310
        }
311
    }
312

313
    protected Object resolve(AbstractHessianDecoder in, Object obj) throws Exception {
314
        // if there's a readResolve method, call it
315
        try {
316
            if (readResolve != null) {
3✔
317
                return readResolve.invoke(obj);
7✔
318
            }
319
        } catch (InvocationTargetException e) {
×
320
            if (e.getCause() instanceof Exception) {
×
321
                throw (Exception) e.getCause();
×
322
            } else {
323
                throw e;
×
324
            }
325
        }
1✔
326

327
        return obj;
2✔
328
    }
329

330
    protected Object instantiate() throws Exception {
331
        try {
332
            if (constructor != null) {
3✔
333
                return constructor.newInstance(constructorArgs);
6✔
334
            } else {
335
                return type.getDeclaredConstructor().newInstance();
×
336
            }
337
        } catch (Exception e) {
1✔
338
            throw new HessianProtocolException("'" + type.getName() + "' could not be instantiated", e);
9✔
339
        }
340
    }
341

342
    /**
343
     * Creates a map of the classes fields.
344
     */
345
    protected HashMap<String, FieldDeserializer2> getFieldMap(Class<?> cl, FieldDeserializer2Factory fieldFactory) {
346
        HashMap<String, FieldDeserializer2> fieldMap = new HashMap<>();
4✔
347

348
        for (; cl != null; cl = cl.getSuperclass()) {
6✔
349
            Field[] fields = cl.getDeclaredFields();
3✔
350
            for (Field field : fields) {
16✔
351
                if (!Modifier.isTransient(field.getModifiers())
5✔
352
                        && !Modifier.isStatic(field.getModifiers())
5✔
353
                        && fieldMap.get(field.getName()) == null) {
3!
354
                    FieldDeserializer2 deser = fieldFactory.create(field);
4✔
355

356
                    fieldMap.put(field.getName(), deser);
6✔
357
                }
358
            }
359
        }
360

361
        return fieldMap;
2✔
362
    }
363

364
    /**
365
     * Creates a map of the classes fields.
366
     */
367
    protected static Object getParamArg(Class<?> cl) {
368
        if (!cl.isPrimitive()) {
3✔
369
            return null;
2✔
370
        } else if (boolean.class.equals(cl)) {
4✔
371
            return Boolean.FALSE;
2✔
372
        } else if (byte.class.equals(cl)) {
4✔
373
            return (byte) 0;
3✔
374
        } else if (short.class.equals(cl)) {
4✔
375
            return (short) 0;
3✔
376
        } else if (char.class.equals(cl)) {
4✔
377
            return (char) 0;
3✔
378
        } else if (int.class.equals(cl)) {
4✔
379
            return 0;
3✔
380
        } else if (long.class.equals(cl)) {
4✔
381
            return 0L;
3✔
382
        } else if (float.class.equals(cl)) {
4✔
383
            return (float) 0;
3✔
384
        } else if (double.class.equals(cl)) {
4!
385
            return (double) 0;
3✔
386
        } else {
387
            throw new UnsupportedOperationException();
×
388
        }
389
    }
390
}
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