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

wuwen5 / hessian / 17834723885

18 Sep 2025 04:10PM UTC coverage: 69.377% (+0.09%) from 69.283%
17834723885

push

github

web-flow
refactor: rename duplicate class names (#48)

* refactor: rename duplicate class names

* chore: license

1843 of 2851 branches covered (64.64%)

Branch coverage included in aggregate %.

4249 of 5930 relevant lines covered (71.65%)

3.11 hits per line

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

82.76
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, HessianSerializer> staticSerializerMap;
81
    private static Map<String, HessianDeserializer> staticDeserializerMap;
82
    private static Map<String, HessianDeserializer> 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, HessianSerializer> serializerClassMap = new HashMap<>();
5✔
91

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

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

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

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

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

102
    private final Map<String, HessianDeserializer> 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 HessianSerializer getSerializer(String className) {
158
        HessianSerializer 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 HessianSerializer getCustomSerializer(Class<?> cl) {
175
        HessianSerializer 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
            HessianSerializer ser =
3✔
187
                    (HessianSerializer) serClass.getDeclaredConstructor().newInstance();
6✔
188

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

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

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

200
        return null;
2✔
201
    }
202

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

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

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

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

219
        return null;
2✔
220
    }
221

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

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

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

241
            HessianDeserializer ser =
3✔
242
                    (HessianDeserializer) serClass.getDeclaredConstructor().newInstance();
6✔
243

244
            customDeserializerMap.put(cl.getName(), ser);
7✔
245

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

253
        customDeserializerMap.put(cl.getName(), BaseDeserializer.NULL);
7✔
254

255
        return null;
2✔
256
    }
257

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

266
            serializerClassMap.putAll(parent.serializerClassMap);
×
267
            deserializerClassMap.putAll(parent.deserializerClassMap);
×
268
        }
269

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

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

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

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

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

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

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

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

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

324
            Enumeration<?> iter;
325

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

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

334
                fileList.add(url.toString());
5✔
335

336
                try (InputStream is = url.openStream()) {
3✔
337

338
                    Properties props = new Properties();
4✔
339
                    props.load(is);
3✔
340

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

345
                        Class<?> apiClass;
346
                        Class<?> serializerClass;
347

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

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

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

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

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

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

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

392
        FieldDeserializer2Factory fieldFactory = FieldDeserializer2Factory.create();
2✔
393

394
        addBasic(void.class, "void", BasicSerializer.NULL);
4✔
395

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

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

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

429
        HessianDeserializer objectDeserializer = new JavaDeserializer(Object.class, fieldFactory);
6✔
430
        staticDeserializerMap.put("object", objectDeserializer);
5✔
431
        staticClassNameMap.put("object", objectDeserializer);
5✔
432

433
        staticSerializerMap.put(Class.class.getName(), new ClassSerializer());
8✔
434

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

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

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

451
        staticSerializerMap.put(InetAddress.class.getName(), InetAddressSerializer.create());
6✔
452

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

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

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

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

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