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

hazendaz / javabean-tester / 3229

16 Feb 2026 12:25AM UTC coverage: 87.5% (-0.4%) from 87.852%
3229

push

github

hazendaz
[gha] Update coverity

285 of 331 branches covered (86.1%)

525 of 600 relevant lines covered (87.5%)

0.88 hits per line

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

96.15
/src/main/java/com/codebox/builders/ExtensionBuilder.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 * See LICENSE file for details.
4
 *
5
 * Copyright 2012-2026 hazendaz
6
 *
7
 * Portions of initial baseline code (getter/setter test) by Rob Dawson (CodeBox)
8
 */
9
package com.codebox.builders;
10

11
import java.util.HashMap;
12
import java.util.Map;
13
import java.util.Map.Entry;
14
import javassist.CannotCompileException;
15
import javassist.ClassPool;
16
import javassist.CtClass;
17
import javassist.CtField;
18
import javassist.CtMethod;
19
import javassist.NotFoundException;
20

21
import org.slf4j.Logger;
22
import org.slf4j.LoggerFactory;
23

24
/**
25
 * ExtensionBuilder dynamically generates a subclass of the given class with additional String properties and their
26
 * getters/setters.
27
 * <p>
28
 * Uses Javassist to create a new class at runtime named <code>clazz.getName() + "Extension"</code>. The generated class
29
 * will have four String properties: jbExtension1, jbExtension2, jbExtension3, jbExtension4.
30
 *
31
 * @param <T>
32
 *            the type to extend
33
 */
34
public class ExtensionBuilder<T> {
1✔
35

36
    /** The Constant logger. */
37
    private static final Logger logger = LoggerFactory.getLogger(ExtensionBuilder.class);
1✔
38

39
    /**
40
     * Generates a dynamic subclass of the given class with additional String properties and their getters/setters.
41
     *
42
     * @param clazz
43
     *            the class to extend
44
     * @return the generated class
45
     * @throws NotFoundException
46
     *             if the class cannot be found in the class pool
47
     * @throws CannotCompileException
48
     *             if the class cannot be compiled
49
     */
50
    public Class<?> generate(final Class<T> clazz) throws NotFoundException, CannotCompileException {
51
        try {
52
            // If extension already recreated, return it
53
            return Class.forName(clazz.getName() + "Extension");
×
54
        } catch (final ClassNotFoundException e) {
1✔
55
            // No extension exists, so create it
56
            ExtensionBuilder.logger.trace("No extension exists, so create it", e);
1✔
57
        }
58

59
        final ClassPool pool = ClassPool.getDefault();
1✔
60
        final CtClass cc = pool.makeClass(clazz.getName() + "Extension");
1✔
61

62
        // add super class
63
        cc.setSuperclass(ExtensionBuilder.resolveCtClass(clazz));
1✔
64

65
        final Map<String, Class<?>> properties = new HashMap<>();
1✔
66
        properties.put("jbExtension1", String.class);
1✔
67
        properties.put("jbExtension2", String.class);
1✔
68
        properties.put("jbExtension3", String.class);
1✔
69
        properties.put("jbExtension4", String.class);
1✔
70

71
        for (final Entry<String, Class<?>> entry : properties.entrySet()) {
1✔
72

73
            // Add field
74
            cc.addField(new CtField(ExtensionBuilder.resolveCtClass(entry.getValue()), entry.getKey(), cc));
1✔
75

76
            // Add getter
77
            cc.addMethod(ExtensionBuilder.generateGetter(cc, entry.getKey(), entry.getValue()));
1✔
78

79
            // Add setter
80
            cc.addMethod(ExtensionBuilder.generateSetter(cc, entry.getKey(), entry.getValue()));
1✔
81
        }
1✔
82

83
        return cc.toClass();
1✔
84
    }
85

86
    /**
87
     * Generates a getter method for the specified field.
88
     *
89
     * @param declaringClass
90
     *            the class to add the method to
91
     * @param fieldName
92
     *            the name of the field
93
     * @param fieldClass
94
     *            the type of the field
95
     * @return the generated getter method
96
     * @throws CannotCompileException
97
     *             if the method cannot be compiled
98
     */
99
    private static CtMethod generateGetter(final CtClass declaringClass, final String fieldName,
100
            final Class<?> fieldClass) throws CannotCompileException {
101
        String methodSrc = """
1✔
102
                public %s get%s() {
103
                    return this.%s;
104
                }
105
                """.formatted(fieldClass.getName(), fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1),
1✔
106
                fieldName);
107
        return CtMethod.make(methodSrc, declaringClass);
1✔
108
    }
109

110
    /**
111
     * Generates a setter method for the specified field.
112
     *
113
     * @param declaringClass
114
     *            the class to add the method to
115
     * @param fieldName
116
     *            the name of the field
117
     * @param fieldClass
118
     *            the type of the field
119
     * @return the generated setter method
120
     * @throws CannotCompileException
121
     *             if the method cannot be compiled
122
     */
123
    private static CtMethod generateSetter(final CtClass declaringClass, final String fieldName,
124
            final Class<?> fieldClass) throws CannotCompileException {
125
        String methodSrc = """
1✔
126
                public void set%s(%s %s) {
127
                    this.%s = %s;
128
                }
129
                """.formatted(fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1), fieldClass.getName(),
1✔
130
                fieldName, fieldName, fieldName);
131
        return CtMethod.make(methodSrc, declaringClass);
1✔
132
    }
133

134
    /**
135
     * Resolves a CtClass from a Java Class using the default class pool.
136
     *
137
     * @param clazz
138
     *            the Java class to resolve
139
     * @return the corresponding CtClass
140
     * @throws NotFoundException
141
     *             if the class cannot be found in the class pool
142
     */
143
    private static CtClass resolveCtClass(final Class<?> clazz) throws NotFoundException {
144
        return ClassPool.getDefault().get(clazz.getName());
1✔
145
    }
146

147
}
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