• 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

82.63
hessian2-codec/src/main/java/io/github/wuwen5/hessian/io/ContextSerializerFactory.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.HessianException;
52
import java.io.InputStream;
53
import java.lang.ref.SoftReference;
54
import java.lang.ref.WeakReference;
55
import java.net.InetAddress;
56
import java.net.URL;
57
import java.util.Enumeration;
58
import java.util.HashMap;
59
import java.util.HashSet;
60
import java.util.Map;
61
import java.util.Properties;
62
import java.util.Set;
63
import java.util.WeakHashMap;
64
import java.util.concurrent.ConcurrentHashMap;
65
import java.util.concurrent.ConcurrentMap;
66
import java.util.logging.Level;
67
import java.util.logging.Logger;
68

69
/**
70
 * The classloader-specific Factory for returning serialization
71
 */
72
public class ContextSerializerFactory {
73
    private static final Logger log = Logger.getLogger(ContextSerializerFactory.class.getName());
4✔
74

75
    private static final WeakHashMap<ClassLoader, SoftReference<ContextSerializerFactory>> CONTEXT_REF_MAP =
4✔
76
            new WeakHashMap<>();
77

78
    private static final ClassLoader SYSTEM_CLASS_LOADER;
79

80
    private static Map<String, Serializer> staticSerializerMap;
81
    private static Map<String, Deserializer> staticDeserializerMap;
82
    private static Map<String, Deserializer> staticClassNameMap;
83

84
    private ContextSerializerFactory parent;
85
    private final WeakReference<ClassLoader> loaderRef;
86

87
    private final Set<String> serializerFiles = new HashSet<>();
5✔
88
    private final Set<String> deserializerFiles = new HashSet<>();
5✔
89

90
    private final Map<String, Serializer> serializerClassMap = new HashMap<>();
5✔
91

92
    private final ConcurrentMap<String, Serializer> customSerializerMap = new ConcurrentHashMap<>();
5✔
93

94
    private final Map<Class<?>, Serializer> serializerInterfaceMap = new HashMap<>();
5✔
95

96
    private final Map<String, Deserializer> deserializerClassMap = new HashMap<>();
5✔
97

98
    private final Map<String, Deserializer> deserializerClassNameMap = new HashMap<>();
5✔
99

100
    private final ConcurrentMap<String, Deserializer> customDeserializerMap = new ConcurrentHashMap<>();
5✔
101

102
    private final Map<String, Deserializer> deserializerInterfaceMap = new HashMap<>();
5✔
103

104
    public ContextSerializerFactory(ContextSerializerFactory parent, ClassLoader loader) {
2✔
105
        if (loader == null) {
2✔
106
            loader = SYSTEM_CLASS_LOADER;
2✔
107
        }
108

109
        loaderRef = new WeakReference<>(loader);
6✔
110

111
        init();
2✔
112
    }
1✔
113

114
    public static ContextSerializerFactory create() {
115
        return create(Thread.currentThread().getContextClassLoader());
4✔
116
    }
117

118
    public static ContextSerializerFactory create(ClassLoader loader) {
119
        synchronized (CONTEXT_REF_MAP) {
4✔
120
            SoftReference<ContextSerializerFactory> factoryRef = CONTEXT_REF_MAP.get(loader);
5✔
121

122
            ContextSerializerFactory factory = null;
2✔
123

124
            if (factoryRef != null) {
2✔
125
                factory = factoryRef.get();
4✔
126
            }
127

128
            if (factory == null) {
2✔
129
                ContextSerializerFactory parent = null;
2✔
130

131
                if (loader != null) {
2✔
132
                    parent = create(loader.getParent());
4✔
133
                }
134

135
                factory = new ContextSerializerFactory(parent, loader);
6✔
136
                factoryRef = new SoftReference<>(factory);
5✔
137

138
                CONTEXT_REF_MAP.put(loader, factoryRef);
5✔
139
            }
140

141
            return factory;
4✔
142
        }
143
    }
144

145
    public ClassLoader getClassLoader() {
146

147
        if (this.loaderRef != null) {
3!
148
            return this.loaderRef.get();
5✔
149
        } else {
150
            return null;
×
151
        }
152
    }
153

154
    /**
155
     * Returns the serializer for a given class.
156
     */
157
    public Serializer getSerializer(String className) {
158
        Serializer serializer = serializerClassMap.get(className);
6✔
159

160
        if (serializer == AbstractSerializer.NULL) {
3!
161
            return null;
×
162
        } else {
163
            return serializer;
2✔
164
        }
165
    }
166

167
    /**
168
     * Returns a custom serializer the class
169
     *
170
     * @param cl the class of the object that needs to be serialized.
171
     *
172
     * @return a serializer object for the serialization.
173
     */
174
    public Serializer getCustomSerializer(Class<?> cl) {
175
        Serializer serializer = customSerializerMap.get(cl.getName());
7✔
176

177
        if (serializer == AbstractSerializer.NULL) {
3✔
178
            return null;
2✔
179
        } else if (serializer != null) {
2!
180
            return serializer;
×
181
        }
182

183
        try {
184
            Class<?> serClass = Class.forName(cl.getName() + "HessianSerializer", false, cl.getClassLoader());
8✔
185

186
            Serializer ser = (Serializer) serClass.getDeclaredConstructor().newInstance();
9✔
187

188
            customSerializerMap.put(cl.getName(), ser);
7✔
189

190
            return ser;
2✔
191
        } catch (ClassNotFoundException e) {
1✔
192
            log.log(Level.ALL, e.toString(), e);
6✔
193
        } catch (Exception e) {
×
194
            throw new HessianException(e);
×
195
        }
1✔
196

197
        customSerializerMap.put(cl.getName(), AbstractSerializer.NULL);
7✔
198

199
        return null;
2✔
200
    }
201

202
    /**
203
     * Returns the deserializer for a given class.
204
     */
205
    public Deserializer getDeserializer(String className) {
206
        Deserializer deserializer = deserializerClassMap.get(className);
6✔
207

208
        if (deserializer != null && deserializer != BaseDeserializer.NULL) {
5!
209
            return deserializer;
2✔
210
        }
211

212
        deserializer = deserializerInterfaceMap.get(className);
6✔
213

214
        if (deserializer != null && deserializer != BaseDeserializer.NULL) {
2!
215
            return deserializer;
×
216
        }
217

218
        return null;
2✔
219
    }
220

221
    /**
222
     * Returns a custom deserializer the class
223
     *
224
     * @param cl the class of the object that needs to be deserialized.
225
     *
226
     * @return a deserializer object for the deserialization.
227
     */
228
    public Deserializer getCustomDeserializer(Class<?> cl) {
229
        Deserializer deserializer = customDeserializerMap.get(cl.getName());
7✔
230

231
        if (deserializer == BaseDeserializer.NULL) {
3✔
232
            return null;
2✔
233
        } else if (deserializer != null) {
2!
234
            return deserializer;
×
235
        }
236

237
        try {
238
            Class<?> serClass = Class.forName(cl.getName() + "HessianDeserializer", false, cl.getClassLoader());
8✔
239

240
            Deserializer ser = (Deserializer) serClass.getDeclaredConstructor().newInstance();
9✔
241

242
            customDeserializerMap.put(cl.getName(), ser);
7✔
243

244
            return ser;
2✔
245
        } catch (ClassNotFoundException e) {
1✔
246
            log.log(Level.ALL, e.toString(), e);
6✔
247
        } catch (Exception e) {
×
248
            throw new HessianException(e);
×
249
        }
1✔
250

251
        customDeserializerMap.put(cl.getName(), BaseDeserializer.NULL);
7✔
252

253
        return null;
2✔
254
    }
255

256
    /**
257
     * Initialize the factory
258
     */
259
    private void init() {
260
        if (parent != null) {
3!
261
            serializerFiles.addAll(parent.serializerFiles);
×
262
            deserializerFiles.addAll(parent.deserializerFiles);
×
263

264
            serializerClassMap.putAll(parent.serializerClassMap);
×
265
            deserializerClassMap.putAll(parent.deserializerClassMap);
×
266
        }
267

268
        if (parent == null) {
3!
269
            serializerClassMap.putAll(staticSerializerMap);
4✔
270
            deserializerClassMap.putAll(staticDeserializerMap);
4✔
271
            deserializerClassNameMap.putAll(staticClassNameMap);
4✔
272
        }
273

274
        Map<Class<?>, Class<?>> classMap = new HashMap<>();
4✔
275
        initSerializerFiles("META-INF/hessian/serializers", serializerFiles, classMap, Serializer.class);
7✔
276

277
        for (Map.Entry<Class<?>, Class<?>> entry : classMap.entrySet()) {
11✔
278
            try {
279
                Serializer ser =
1✔
280
                        (Serializer) entry.getValue().getDeclaredConstructor().newInstance();
10✔
281

282
                if (entry.getKey().isInterface()) {
5✔
283
                    serializerInterfaceMap.put(entry.getKey(), ser);
9✔
284
                } else {
285
                    serializerClassMap.put(entry.getKey().getName(), ser);
9✔
286
                }
287
            } catch (Exception e) {
×
288
                throw new HessianException(e);
×
289
            }
1✔
290
        }
1✔
291

292
        classMap = new HashMap<>();
4✔
293
        initSerializerFiles("META-INF/hessian/deserializers", deserializerFiles, classMap, Deserializer.class);
7✔
294

295
        for (Map.Entry<Class<?>, Class<?>> entry : classMap.entrySet()) {
11✔
296
            try {
297
                Deserializer ser =
1✔
298
                        (Deserializer) entry.getValue().getDeclaredConstructor().newInstance();
10✔
299

300
                if (entry.getKey().isInterface()) {
5!
301
                    deserializerInterfaceMap.put(entry.getKey().getName(), ser);
×
302
                } else {
303
                    deserializerClassMap.put(entry.getKey().getName(), ser);
9✔
304
                }
305
            } catch (Exception e) {
×
306
                throw new HessianException(e);
×
307
            }
1✔
308
        }
1✔
309
    }
1✔
310

311
    private void initSerializerFiles(
312
            String fileName, Set<String> fileList, Map<Class<?>, Class<?>> classMap, Class<?> type) {
313
        try {
314
            ClassLoader classLoader = getClassLoader();
3✔
315

316
            // on systems with the security manager enabled, the system classloader
317
            // is null
318
            if (classLoader == null) {
2!
319
                return;
×
320
            }
321

322
            Enumeration<?> iter;
323

324
            iter = classLoader.getResources(fileName);
4✔
325
            while (iter.hasMoreElements()) {
3✔
326
                URL url = (URL) iter.nextElement();
4✔
327

328
                if (fileList.contains(url.toString())) {
5!
329
                    continue;
×
330
                }
331

332
                fileList.add(url.toString());
5✔
333

334
                try (InputStream is = url.openStream()) {
3✔
335

336
                    Properties props = new Properties();
4✔
337
                    props.load(is);
3✔
338

339
                    for (Map.Entry<Object, Object> entry : props.entrySet()) {
11✔
340
                        String apiName = (String) entry.getKey();
4✔
341
                        String serializerName = (String) entry.getValue();
4✔
342

343
                        Class<?> apiClass;
344
                        Class<?> serializerClass;
345

346
                        try {
347
                            apiClass = Class.forName(apiName, false, classLoader);
5✔
348
                        } catch (ClassNotFoundException e) {
1✔
349
                            log.fine(url + ": " + apiName + " is not available in this context: " + getClassLoader());
9✔
350
                            continue;
1✔
351
                        }
1✔
352

353
                        try {
354
                            serializerClass = Class.forName(serializerName, false, classLoader);
5✔
355
                        } catch (ClassNotFoundException e) {
×
356
                            log.fine(url + ": " + serializerName + " is not available in this context: "
×
357
                                    + getClassLoader());
×
358
                            continue;
×
359
                        }
1✔
360

361
                        if (!type.isAssignableFrom(serializerClass)) {
4!
362
                            throw new HessianException(url + ": " + serializerClass.getName()
×
363
                                    + " is invalid because it does not implement " + type.getName());
×
364
                        }
365

366
                        classMap.put(apiClass, serializerClass);
5✔
367
                    }
1✔
368
                }
369
            }
1✔
370
        } catch (RuntimeException e) {
×
371
            throw e;
×
372
        } catch (Exception e) {
×
373
            throw new HessianException(e);
×
374
        }
1✔
375
    }
1✔
376

377
    private static void addBasic(Class<?> cl, String typeName, int type) {
378
        staticSerializerMap.put(cl.getName(), new BasicSerializer(type));
9✔
379

380
        Deserializer deserializer = new BasicDeserializer(type);
5✔
381
        staticDeserializerMap.put(cl.getName(), deserializer);
6✔
382
        staticClassNameMap.put(typeName, deserializer);
5✔
383
    }
1✔
384

385
    static {
386
        staticSerializerMap = new HashMap<>();
4✔
387
        staticDeserializerMap = new HashMap<>();
4✔
388
        staticClassNameMap = new HashMap<>();
4✔
389

390
        FieldDeserializer2Factory fieldFactory = FieldDeserializer2Factory.create();
2✔
391

392
        addBasic(void.class, "void", BasicSerializer.NULL);
4✔
393

394
        addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN);
4✔
395
        addBasic(Byte.class, "byte", BasicSerializer.BYTE);
4✔
396
        addBasic(Short.class, "short", BasicSerializer.SHORT);
4✔
397
        addBasic(Integer.class, "int", BasicSerializer.INTEGER);
4✔
398
        addBasic(Long.class, "long", BasicSerializer.LONG);
4✔
399
        addBasic(Float.class, "float", BasicSerializer.FLOAT);
4✔
400
        addBasic(Double.class, "double", BasicSerializer.DOUBLE);
4✔
401
        addBasic(Character.class, "char", BasicSerializer.CHARACTER_OBJECT);
4✔
402
        addBasic(String.class, "string", BasicSerializer.STRING);
4✔
403
        addBasic(Object.class, "object", BasicSerializer.OBJECT);
4✔
404
        addBasic(java.util.Date.class, "date", BasicSerializer.DATE);
4✔
405

406
        addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN);
4✔
407
        addBasic(byte.class, "byte", BasicSerializer.BYTE);
4✔
408
        addBasic(short.class, "short", BasicSerializer.SHORT);
4✔
409
        addBasic(int.class, "int", BasicSerializer.INTEGER);
4✔
410
        addBasic(long.class, "long", BasicSerializer.LONG);
4✔
411
        addBasic(float.class, "float", BasicSerializer.FLOAT);
4✔
412
        addBasic(double.class, "double", BasicSerializer.DOUBLE);
4✔
413
        addBasic(char.class, "char", BasicSerializer.CHARACTER);
4✔
414

415
        addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY);
4✔
416
        addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY);
4✔
417
        staticSerializerMap.put(byte[].class.getName(), ByteArraySerializer.SER);
6✔
418
        addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY);
4✔
419
        addBasic(int[].class, "[int", BasicSerializer.INTEGER_ARRAY);
4✔
420
        addBasic(long[].class, "[long", BasicSerializer.LONG_ARRAY);
4✔
421
        addBasic(float[].class, "[float", BasicSerializer.FLOAT_ARRAY);
4✔
422
        addBasic(double[].class, "[double", BasicSerializer.DOUBLE_ARRAY);
4✔
423
        addBasic(char[].class, "[char", BasicSerializer.CHARACTER_ARRAY);
4✔
424
        addBasic(String[].class, "[string", BasicSerializer.STRING_ARRAY);
4✔
425
        addBasic(Object[].class, "[object", BasicSerializer.OBJECT_ARRAY);
4✔
426

427
        Deserializer objectDeserializer = new JavaDeserializer(Object.class, fieldFactory);
6✔
428
        staticDeserializerMap.put("object", objectDeserializer);
5✔
429
        staticClassNameMap.put("object", objectDeserializer);
5✔
430

431
        staticSerializerMap.put(Class.class.getName(), new ClassSerializer());
8✔
432

433
        staticDeserializerMap.put(Number.class.getName(), new BasicDeserializer(BasicSerializer.NUMBER));
9✔
434

435
        /*
436
        for (Class cl : new Class[] { BigDecimal.class, File.class, ObjectName.class }) {
437
          _staticSerializerMap.put(cl, StringValueSerializer.SER);
438
          _staticDeserializerMap.put(cl, new StringValueDeserializer(cl));
439
        }
440

441
        _staticSerializerMap.put(ObjectName.class, StringValueSerializer.SER);
442
        try {
443
          _staticDeserializerMap.put(ObjectName.class,
444
                               new StringValueDeserializer(ObjectName.class));
445
        } catch (Throwable e) {
446
        }
447
        */
448

449
        staticSerializerMap.put(InetAddress.class.getName(), InetAddressSerializer.create());
6✔
450

451
        staticSerializerMap.put(java.sql.Date.class.getName(), new SqlDateSerializer());
8✔
452
        staticSerializerMap.put(java.sql.Time.class.getName(), new SqlDateSerializer());
8✔
453
        staticSerializerMap.put(java.sql.Timestamp.class.getName(), new SqlDateSerializer());
8✔
454

455
        staticDeserializerMap.put(java.sql.Date.class.getName(), new SqlDateDeserializer(java.sql.Date.class));
9✔
456
        staticDeserializerMap.put(java.sql.Time.class.getName(), new SqlDateDeserializer(java.sql.Time.class));
9✔
457
        staticDeserializerMap.put(
4✔
458
                java.sql.Timestamp.class.getName(), new SqlDateDeserializer(java.sql.Timestamp.class));
5✔
459

460
        // hessian/3bb5
461
        staticDeserializerMap.put(StackTraceElement.class.getName(), new StackTraceElementDeserializer(fieldFactory));
9✔
462

463
        ClassLoader systemClassLoader = null;
2✔
464
        try {
465
            systemClassLoader = ClassLoader.getSystemClassLoader();
2✔
466
        } catch (Exception ignored) {
×
467
        }
1✔
468

469
        SYSTEM_CLASS_LOADER = systemClassLoader;
2✔
470
    }
1✔
471
}
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