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

mybatis / generator / 1722

06 Jul 2025 06:38PM UTC coverage: 88.195% (-0.1%) from 88.307%
1722

push

github

hazendaz
Setup subproject for new Java File Merger

2518 of 3420 branches covered (73.63%)

0 of 16 new or added lines in 3 files covered. (0.0%)

73 existing lines in 3 files now uncovered.

11192 of 12690 relevant lines covered (88.2%)

0.88 hits per line

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

77.87
/core/mybatis-generator-core/src/main/java/org/mybatis/generator/internal/ObjectFactory.java
1
/*
2
 *    Copyright 2006-2025 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.stringHasValue;
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

25
import org.mybatis.generator.api.CommentGenerator;
26
import org.mybatis.generator.api.ConnectionFactory;
27
import org.mybatis.generator.api.FullyQualifiedTable;
28
import org.mybatis.generator.api.IntrospectedColumn;
29
import org.mybatis.generator.api.IntrospectedTable;
30
import org.mybatis.generator.api.JavaFileMerger;
31
import org.mybatis.generator.api.JavaFormatter;
32
import org.mybatis.generator.api.JavaTypeResolver;
33
import org.mybatis.generator.api.KotlinFormatter;
34
import org.mybatis.generator.api.Plugin;
35
import org.mybatis.generator.api.XmlFormatter;
36
import org.mybatis.generator.api.dom.DefaultJavaFormatter;
37
import org.mybatis.generator.api.dom.DefaultKotlinFormatter;
38
import org.mybatis.generator.api.dom.DefaultXmlFormatter;
39
import org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl;
40
import org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3SimpleImpl;
41
import org.mybatis.generator.config.CommentGeneratorConfiguration;
42
import org.mybatis.generator.config.ConnectionFactoryConfiguration;
43
import org.mybatis.generator.config.Context;
44
import org.mybatis.generator.config.JavaTypeResolverConfiguration;
45
import org.mybatis.generator.config.PluginConfiguration;
46
import org.mybatis.generator.config.PropertyRegistry;
47
import org.mybatis.generator.config.TableConfiguration;
48
import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
49
import org.mybatis.generator.runtime.dynamic.sql.IntrospectedTableMyBatis3DynamicSqlImpl;
50
import org.mybatis.generator.runtime.kotlin.IntrospectedTableKotlinImpl;
51

52
/**
53
 * This class creates the different objects needed by the generator.
54
 *
55
 * @author Jeff Butler
56
 */
57
public class ObjectFactory {
58

59
    private static final List<ClassLoader> externalClassLoaders;
60

61
    static {
62
        externalClassLoaders = new ArrayList<>();
1✔
63
    }
1✔
64

65
    /**
66
     * Utility class. No instances allowed.
67
     */
68
    private ObjectFactory() {
69
        super();
70
    }
71

72
    /**
73
     * Clears the class loaders.  This method should be called at the beginning of
74
     * a generation run so that and change to the classloading configuration
75
     * will be reflected.  For example, if the eclipse launcher changes configuration
76
     * it might not be updated if eclipse hasn't been restarted.
77
     *
78
     */
79
    public static void reset() {
80
        externalClassLoaders.clear();
1✔
81
    }
1✔
82

83
    /**
84
     * Adds a custom classloader to the collection of classloaders searched for "external" classes. These are classes
85
     * that do not depend on any of the generator's classes or interfaces. Examples are JDBC drivers, root classes, root
86
     * interfaces, etc.
87
     *
88
     * @param classLoader
89
     *            the class loader
90
     */
91
    public static synchronized void addExternalClassLoader(
92
            ClassLoader classLoader) {
93
        ObjectFactory.externalClassLoaders.add(classLoader);
×
UNCOV
94
    }
×
95

96
    /**
97
     * Returns a class loaded from the context classloader, or the classloader supplied by a client. This is
98
     * appropriate for JDBC drivers, model root classes, etc. It is not appropriate for any class that extends one of
99
     * the supplied classes or interfaces.
100
     *
101
     * @param type
102
     *            the type
103
     * @return the Class loaded from the external classloader
104
     * @throws ClassNotFoundException
105
     *             the class not found exception
106
     */
107
    public static Class<?> externalClassForName(String type)
108
            throws ClassNotFoundException {
109

110
        Class<?> clazz;
111

112
        for (ClassLoader classLoader : externalClassLoaders) {
1!
113
            try {
114
                clazz = Class.forName(type, true, classLoader);
×
115
                return clazz;
×
UNCOV
116
            } catch (Exception e) {
×
117
                // ignore - fail safe below
118
            }
UNCOV
119
        }
×
120

121
        return internalClassForName(type);
1✔
122
    }
123

124
    public static Object createExternalObject(String type) {
125
        Object answer;
126

127
        try {
128
            Class<?> clazz = externalClassForName(type);
×
129
            answer = clazz.getConstructor().newInstance();
×
130
        } catch (Exception e) {
×
UNCOV
131
            throw new RuntimeException(getString(
×
132
                    "RuntimeError.6", type), e); //$NON-NLS-1$
UNCOV
133
        }
×
134

UNCOV
135
        return answer;
×
136
    }
137

138
    public static Class<?> internalClassForName(String type)
139
            throws ClassNotFoundException {
140
        Class<?> clazz = null;
1✔
141

142
        try {
143
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
1✔
144
            clazz = Class.forName(type, true, cl);
1✔
145
        } catch (Exception e) {
1✔
146
            // ignore - failsafe below
147
        }
1✔
148

149
        if (clazz == null) {
1✔
UNCOV
150
            clazz = Class.forName(type, true, ObjectFactory.class.getClassLoader());
×
151
        }
152

153
        return clazz;
1✔
154
    }
155

156
    public static URL getResource(String resource) {
157
        URL url;
158

159
        for (ClassLoader classLoader : externalClassLoaders) {
1!
160
            url = classLoader.getResource(resource);
×
161
            if (url != null) {
×
UNCOV
162
                return url;
×
163
            }
UNCOV
164
        }
×
165

166
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
1✔
167
        url = cl.getResource(resource);
1✔
168

169
        if (url == null) {
1!
UNCOV
170
            url = ObjectFactory.class.getClassLoader().getResource(resource);
×
171
        }
172

173
        return url;
1✔
174
    }
175

176
    public static Object createInternalObject(String type) {
177
        Object answer;
178

179
        try {
180
            Class<?> clazz = internalClassForName(type);
1✔
181

182
            answer = clazz.getConstructor().newInstance();
1✔
183
        } catch (Exception e) {
×
UNCOV
184
            throw new RuntimeException(getString(
×
185
                    "RuntimeError.6", type), e); //$NON-NLS-1$
186

187
        }
1✔
188

189
        return answer;
1✔
190
    }
191

192
    public static JavaTypeResolver createJavaTypeResolver(Context context,
193
            List<String> warnings) {
194
        JavaTypeResolverConfiguration config = context
1✔
195
                .getJavaTypeResolverConfiguration();
1✔
196
        String type;
197

198
        if (config != null && config.getConfigurationType() != null) {
1!
199
            type = config.getConfigurationType();
×
200
            if ("DEFAULT".equalsIgnoreCase(type)) { //$NON-NLS-1$
×
UNCOV
201
                type = JavaTypeResolverDefaultImpl.class.getName();
×
202
            }
203
        } else {
204
            type = JavaTypeResolverDefaultImpl.class.getName();
1✔
205
        }
206

207
        JavaTypeResolver answer = (JavaTypeResolver) createInternalObject(type);
1✔
208
        answer.setWarnings(warnings);
1✔
209

210
        if (config != null) {
1✔
211
            answer.addConfigurationProperties(config.getProperties());
1✔
212
        }
213

214
        answer.setContext(context);
1✔
215

216
        return answer;
1✔
217
    }
218

219
    public static Plugin createPlugin(Context context,
220
            PluginConfiguration pluginConfiguration) {
221
        Plugin plugin = (Plugin) createInternalObject(pluginConfiguration
1✔
222
                .getConfigurationType());
1✔
223
        plugin.setContext(context);
1✔
224
        plugin.setProperties(pluginConfiguration.getProperties());
1✔
225
        return plugin;
1✔
226
    }
227

228
    public static CommentGenerator createCommentGenerator(Context context) {
229

230
        CommentGeneratorConfiguration config = context
1✔
231
                .getCommentGeneratorConfiguration();
1✔
232
        CommentGenerator answer;
233

234
        String type;
235
        if (config == null || config.getConfigurationType() == null) {
1!
236
            type = DefaultCommentGenerator.class.getName();
1✔
237
        } else {
UNCOV
238
            type = config.getConfigurationType();
×
239
        }
240

241
        answer = (CommentGenerator) createInternalObject(type);
1✔
242

243
        if (config != null) {
1✔
244
            answer.addConfigurationProperties(config.getProperties());
1✔
245
        }
246

247
        return answer;
1✔
248
    }
249

250
    public static ConnectionFactory createConnectionFactory(Context context) {
251

252
        ConnectionFactoryConfiguration config = context
1✔
253
                .getConnectionFactoryConfiguration();
1✔
254
        ConnectionFactory answer;
255

256
        String type;
257
        if (config == null || config.getConfigurationType() == null) {
1!
258
            type = JDBCConnectionFactory.class.getName();
1✔
259
        } else {
UNCOV
260
            type = config.getConfigurationType();
×
261
        }
262

263
        answer = (ConnectionFactory) createInternalObject(type);
1✔
264

265
        if (config != null) {
1!
266
            answer.addConfigurationProperties(config.getProperties());
1✔
267
        }
268

269
        return answer;
1✔
270
    }
271

272
    public static JavaFormatter createJavaFormatter(Context context) {
273
        String type = context.getProperty(PropertyRegistry.CONTEXT_JAVA_FORMATTER);
1✔
274
        if (!stringHasValue(type)) {
1!
275
            type = DefaultJavaFormatter.class.getName();
1✔
276
        }
277

278
        JavaFormatter answer = (JavaFormatter) createInternalObject(type);
1✔
279

280
        answer.setContext(context);
1✔
281

282
        return answer;
1✔
283
    }
284

285
    public static KotlinFormatter createKotlinFormatter(Context context) {
286
        String type = context.getProperty(PropertyRegistry.CONTEXT_KOTLIN_FORMATTER);
1✔
287
        if (!stringHasValue(type)) {
1!
288
            type = DefaultKotlinFormatter.class.getName();
1✔
289
        }
290

291
        KotlinFormatter answer = (KotlinFormatter) createInternalObject(type);
1✔
292

293
        answer.setContext(context);
1✔
294

295
        return answer;
1✔
296
    }
297

298
    public static XmlFormatter createXmlFormatter(Context context) {
299
        String type = context.getProperty(PropertyRegistry.CONTEXT_XML_FORMATTER);
1✔
300
        if (!stringHasValue(type)) {
1!
301
            type = DefaultXmlFormatter.class.getName();
1✔
302
        }
303

304
        XmlFormatter answer = (XmlFormatter) createInternalObject(type);
1✔
305

306
        answer.setContext(context);
1✔
307

308
        return answer;
1✔
309
    }
310

311
    public static JavaFileMerger createJavaFileMerger(String type) {
NEW
UNCOV
312
        JavaFileMerger answer = (JavaFileMerger) createInternalObject(type);
×
NEW
UNCOV
313
        return answer;
×
314
    }
315

316
    public static IntrospectedTable createIntrospectedTable(
317
            TableConfiguration tableConfiguration, FullyQualifiedTable table,
318
            Context context) {
319

320
        IntrospectedTable answer = createIntrospectedTableForValidation(context);
1✔
321
        answer.setFullyQualifiedTable(table);
1✔
322
        answer.setTableConfiguration(tableConfiguration);
1✔
323

324
        return answer;
1✔
325
    }
326

327
    /**
328
     * Creates an introspected table implementation that is only usable for validation .
329
     *
330
     *
331
     * @param context
332
     *            the context
333
     * @return the introspected table
334
     */
335
    public static IntrospectedTable createIntrospectedTableForValidation(Context context) {
336
        String type = context.getTargetRuntime();
1✔
337
        if (!stringHasValue(type)) {
1✔
338
            type = IntrospectedTableMyBatis3DynamicSqlImpl.class.getName();
1✔
339
        } else if ("MyBatis3".equalsIgnoreCase(type)) { //$NON-NLS-1$
1✔
340
            type = IntrospectedTableMyBatis3Impl.class.getName();
1✔
341
        } else if ("MyBatis3Simple".equalsIgnoreCase(type)) { //$NON-NLS-1$
1✔
342
            type = IntrospectedTableMyBatis3SimpleImpl.class.getName();
1✔
343
        } else if ("MyBatis3DynamicSql".equalsIgnoreCase(type)) { //$NON-NLS-1$
1✔
344
            type = IntrospectedTableMyBatis3DynamicSqlImpl.class.getName();
1✔
345
        } else if ("MyBatis3Kotlin".equalsIgnoreCase(type)) { //$NON-NLS-1$
1!
346
            type = IntrospectedTableKotlinImpl.class.getName();
1✔
347
        }
348

349
        IntrospectedTable answer = (IntrospectedTable) createInternalObject(type);
1✔
350
        answer.setContext(context);
1✔
351

352
        return answer;
1✔
353
    }
354

355
    public static IntrospectedColumn createIntrospectedColumn(Context context) {
356
        String type = context.getIntrospectedColumnImpl();
1✔
357
        if (!stringHasValue(type)) {
1!
358
            type = IntrospectedColumn.class.getName();
1✔
359
        }
360

361
        IntrospectedColumn answer = (IntrospectedColumn) createInternalObject(type);
1✔
362
        answer.setContext(context);
1✔
363

364
        return answer;
1✔
365
    }
366
}
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