• 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

78.99
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());
×
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());
×
185

186
            Serializer ser = (Serializer) serClass.newInstance();
×
187

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

190
            return ser;
×
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());
×
239

240
            Deserializer ser = (Deserializer) serClass.newInstance();
×
241

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

244
            return ser;
×
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 = (Serializer) entry.getValue().newInstance();
6✔
280

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

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

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

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

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

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

320
            Enumeration<?> iter;
321

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

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

330
                fileList.add(url.toString());
5✔
331

332
                try (InputStream is = url.openStream()) {
3✔
333

334
                    Properties props = new Properties();
4✔
335
                    props.load(is);
3✔
336

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

341
                        Class<?> apiClass;
342
                        Class<?> serializerClass;
343

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

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

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

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

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

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

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

388
        FieldDeserializer2Factory fieldFactory = FieldDeserializer2Factory.create();
2✔
389

390
        addBasic(void.class, "void", BasicSerializer.NULL);
4✔
391

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

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

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

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

429
        staticSerializerMap.put(Class.class.getName(), new ClassSerializer());
8✔
430

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

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

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

447
        staticSerializerMap.put(InetAddress.class.getName(), InetAddressSerializer.create());
6✔
448

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

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

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

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

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