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

mybatis / generator / 2146

07 Apr 2026 03:14PM UTC coverage: 91.703% (+0.02%) from 91.685%
2146

push

github

web-flow
Merge pull request #1489 from jeffgbutler/misc-updates

Miscellaneous Updates

2436 of 3134 branches covered (77.73%)

58 of 60 new or added lines in 6 files covered. (96.67%)

2 existing lines in 1 file now uncovered.

11892 of 12968 relevant lines covered (91.7%)

0.92 hits per line

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

76.19
/core/mybatis-generator-core/src/main/java/org/mybatis/generator/internal/ObjectFactory.java
1
/*
2
 *    Copyright 2006-2026 the original author or authors.
3
 *
4
 *    Licensed under the Apache License, Version 2.0 (the "License");
5
 *    you may not use this file except in compliance with the License.
6
 *    You may obtain a copy of the License at
7
 *
8
 *       https://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 *    Unless required by applicable law or agreed to in writing, software
11
 *    distributed under the License is distributed on an "AS IS" BASIS,
12
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 *    See the License for the specific language governing permissions and
14
 *    limitations under the License.
15
 */
16
package org.mybatis.generator.internal;
17

18
import static org.mybatis.generator.internal.util.StringUtility.stringValueOrElse;
19
import static org.mybatis.generator.internal.util.messages.Messages.getString;
20

21
import java.net.URL;
22
import java.util.ArrayList;
23
import java.util.List;
24
import java.util.Optional;
25

26
import org.mybatis.generator.api.CommentGenerator;
27
import org.mybatis.generator.api.ConnectionFactory;
28
import org.mybatis.generator.api.IntrospectedColumn;
29
import org.mybatis.generator.api.JavaFormatter;
30
import org.mybatis.generator.api.JavaTypeResolver;
31
import org.mybatis.generator.api.KnownRuntime;
32
import org.mybatis.generator.api.KotlinFormatter;
33
import org.mybatis.generator.api.Plugin;
34
import org.mybatis.generator.api.XmlFormatter;
35
import org.mybatis.generator.config.CommentGeneratorConfiguration;
36
import org.mybatis.generator.config.ConnectionFactoryConfiguration;
37
import org.mybatis.generator.config.Context;
38
import org.mybatis.generator.config.Defaults;
39
import org.mybatis.generator.config.JavaTypeResolverConfiguration;
40
import org.mybatis.generator.config.PluginConfiguration;
41
import org.mybatis.generator.config.PropertyRegistry;
42
import org.mybatis.generator.exception.InternalException;
43

44
/**
45
 * This class creates the different objects needed by the generator.
46
 *
47
 * @author Jeff Butler
48
 */
49
public class ObjectFactory {
50

51
    private static final List<ClassLoader> externalClassLoaders;
52

53
    static {
54
        externalClassLoaders = new ArrayList<>();
1✔
55
    }
1✔
56

57
    /**
58
     * Utility class. No instances allowed.
59
     */
60
    private ObjectFactory() {
61
        super();
62
    }
63

64
    /**
65
     * Clears the class loaders.  This method should be called at the beginning of
66
     * a generation run so that and change to the classloading configuration
67
     * will be reflected.  For example, if the eclipse launcher changes configuration
68
     * it might not be updated if eclipse hasn't been restarted.
69
     *
70
     */
71
    public static void reset() {
72
        externalClassLoaders.clear();
1✔
73
    }
1✔
74

75
    /**
76
     * Adds a custom classloader to the collection of classloaders searched for "external" classes. These are classes
77
     * that do not depend on any of the generator's classes or interfaces. Examples are JDBC drivers, root classes, root
78
     * interfaces, etc.
79
     *
80
     * @param classLoader
81
     *            the class loader
82
     */
83
    public static synchronized void addExternalClassLoader(ClassLoader classLoader) {
NEW
84
        externalClassLoaders.add(classLoader);
×
85
    }
×
86

87
    /**
88
     * Returns a class loaded from the context classloader, or the classloader supplied by a client. This is
89
     * appropriate for JDBC drivers, model root classes, etc. It is not appropriate for any class that extends one of
90
     * the supplied classes or interfaces.
91
     *
92
     * @param type
93
     *            the type
94
     * @return the Class loaded from the external classloader
95
     * @throws ClassNotFoundException
96
     *             the class not found exception
97
     */
98
    @SuppressWarnings("unchecked")
99
    public static <T> Class<T> externalClassForName(String type) throws ClassNotFoundException {
100
        Class<T> clazz;
101

102
        for (ClassLoader classLoader : externalClassLoaders) {
1!
103
            try {
104
                clazz = (Class<T>) Class.forName(type, true, classLoader);
×
105
                return clazz;
×
106
            } catch (Exception e) {
×
107
                // ignore - fail safe below
108
            }
109
        }
×
110

111
        return internalClassForName(type);
1✔
112
    }
113

114
    public static <T> T createExternalObject(String type) {
115
        T answer;
116

117
        try {
118
            Class<T> clazz = externalClassForName(type);
×
119
            answer = clazz.getConstructor().newInstance();
×
120
        } catch (Exception e) {
×
121
            throw new InternalException(getString("RuntimeError.6", type), e); //$NON-NLS-1$
×
122
        }
×
123

124
        return answer;
×
125
    }
126

127
    @SuppressWarnings("unchecked")
128
    public static <T> Class<T> internalClassForName(String type) throws ClassNotFoundException {
129
        Class<?> clazz;
130
        try {
131
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
1✔
132
            clazz = Class.forName(type, true, cl);
1✔
133
        } catch (Exception e) {
1✔
134
            // ignore - failsafe below
135
            clazz = null;
1✔
136
        }
1✔
137

138
        if (clazz == null) {
1✔
139
            clazz = Class.forName(type, true, ObjectFactory.class.getClassLoader());
×
140
        }
141

142
        return (Class<T>) clazz;
1✔
143
    }
144

145
    public static Optional<URL> getResource(String resource) {
146
        URL url;
147

148
        for (ClassLoader classLoader : externalClassLoaders) {
1!
149
            url = classLoader.getResource(resource);
×
150
            if (url != null) {
×
151
                return Optional.of(url);
×
152
            }
153
        }
×
154

155
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
1✔
156
        url = cl.getResource(resource);
1✔
157

158
        if (url == null) {
1!
159
            url = ObjectFactory.class.getClassLoader().getResource(resource);
×
160
        }
161

162
        return Optional.ofNullable(url);
1✔
163
    }
164

165
    public static <T> T createInternalObject(String type) {
166
        T answer;
167

168
        try {
169
            Class<T> clazz = internalClassForName(type);
1✔
170
            answer = clazz.getConstructor().newInstance();
1✔
171
        } catch (Exception e) {
×
172
            throw new InternalException(getString("RuntimeError.6", type), e); //$NON-NLS-1$
×
173
        }
1✔
174

175
        return answer;
1✔
176
    }
177

178
    public static JavaTypeResolver createJavaTypeResolver(Context context, List<String> warnings) {
179
        String type = context.getJavaTypeResolverConfiguration()
1✔
180
                .map(JavaTypeResolverConfiguration::getImplementationType)
1✔
181
                .orElse(Defaults.DEFAULT_JAVA_TYPE_RESOLVER);
1✔
182

183
        JavaTypeResolver answer = createInternalObject(type);
1✔
184
        answer.setWarnings(warnings);
1✔
185

186
        context.getJavaTypeResolverConfiguration()
1✔
187
                .ifPresent(c -> answer.addConfigurationProperties(c.getProperties()));
1✔
188

189
        answer.setContext(context);
1✔
190

191
        return answer;
1✔
192
    }
193

194
    public static Plugin createPlugin(Context context, PluginConfiguration pluginConfiguration,
195
                                      CommentGenerator commentGenerator, KnownRuntime knownRuntime) {
196
        Plugin plugin = createInternalObject(pluginConfiguration.getConfigurationType().orElseThrow());
1✔
197
        plugin.setContext(context);
1✔
198
        plugin.setProperties(pluginConfiguration.getProperties());
1✔
199
        plugin.setCommentGenerator(commentGenerator);
1✔
200
        plugin.setKnownRuntime(knownRuntime);
1✔
201
        return plugin;
1✔
202
    }
203

204
    public static CommentGenerator createCommentGenerator(Context context) {
205
        CommentGenerator answer;
206

207
        String type = context.getCommentGeneratorConfiguration()
1✔
208
                .map(CommentGeneratorConfiguration::getImplementationType)
1✔
209
                .orElse(Defaults.DEFAULT_COMMENT_GENERATOR);
1✔
210

211
        answer = createInternalObject(type);
1✔
212

213
        context.getCommentGeneratorConfiguration()
1✔
214
                .ifPresent(c -> answer.addConfigurationProperties(c.getProperties()));
1✔
215

216
        return answer;
1✔
217
    }
218

219
    public static ConnectionFactory createConnectionFactory(ConnectionFactoryConfiguration config) {
220
        ConnectionFactory answer;
221

222
        String type = config.getImplementationType();
1✔
223

224
        answer = createInternalObject(type);
1✔
225
        answer.addConfigurationProperties(config.getProperties());
1✔
226

227
        return answer;
1✔
228
    }
229

230
    public static JavaFormatter createJavaFormatter(Context context) {
231
        String type = stringValueOrElse(context.getProperty(PropertyRegistry.CONTEXT_JAVA_FORMATTER),
1✔
232
                Defaults.DEFAULT_JAVA_FORMATTER);
233
        JavaFormatter answer = createInternalObject(type);
1✔
234

235
        answer.setContext(context);
1✔
236

237
        return answer;
1✔
238
    }
239

240
    public static KotlinFormatter createKotlinFormatter(Context context) {
241
        String type = stringValueOrElse(context.getProperty(PropertyRegistry.CONTEXT_KOTLIN_FORMATTER),
1✔
242
                Defaults.DEFAULT_KOTLIN_FORMATTER);
243
        KotlinFormatter answer = createInternalObject(type);
1✔
244

245
        answer.setContext(context);
1✔
246

247
        return answer;
1✔
248
    }
249

250
    public static XmlFormatter createXmlFormatter(Context context) {
251
        String type = stringValueOrElse(context.getProperty(PropertyRegistry.CONTEXT_XML_FORMATTER),
1✔
252
                Defaults.DEFAULT_XML_FORMATTER);
253
        XmlFormatter answer = createInternalObject(type);
1✔
254

255
        answer.setContext(context);
1✔
256

257
        return answer;
1✔
258
    }
259

260
    public static IntrospectedColumn createIntrospectedColumn(Context context) {
261
        String type = context.getIntrospectedColumnImpl().orElse(IntrospectedColumn.class.getName());
1✔
262
        IntrospectedColumn answer = createInternalObject(type);
1✔
263
        answer.setContext(context);
1✔
264

265
        return answer;
1✔
266
    }
267
}
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