1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
46
47
48
49 public class ObjectFactory {
50
51 private static final List<ClassLoader> externalClassLoaders;
52
53 static {
54 externalClassLoaders = new ArrayList<>();
55 }
56
57
58
59
60 private ObjectFactory() {
61 super();
62 }
63
64
65
66
67
68
69
70
71 public static void reset() {
72 externalClassLoaders.clear();
73 }
74
75
76
77
78
79
80
81
82
83 public static synchronized void addExternalClassLoader(ClassLoader classLoader) {
84 externalClassLoaders.add(classLoader);
85 }
86
87
88
89
90
91
92
93
94
95
96
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) {
103 try {
104 clazz = (Class<T>) Class.forName(type, true, classLoader);
105 return clazz;
106 } catch (Exception e) {
107
108 }
109 }
110
111 return internalClassForName(type);
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);
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();
132 clazz = Class.forName(type, true, cl);
133 } catch (Exception e) {
134
135 clazz = null;
136 }
137
138 if (clazz == null) {
139 clazz = Class.forName(type, true, ObjectFactory.class.getClassLoader());
140 }
141
142 return (Class<T>) clazz;
143 }
144
145 public static Optional<URL> getResource(String resource) {
146 URL url;
147
148 for (ClassLoader classLoader : externalClassLoaders) {
149 url = classLoader.getResource(resource);
150 if (url != null) {
151 return Optional.of(url);
152 }
153 }
154
155 ClassLoader cl = Thread.currentThread().getContextClassLoader();
156 url = cl.getResource(resource);
157
158 if (url == null) {
159 url = ObjectFactory.class.getClassLoader().getResource(resource);
160 }
161
162 return Optional.ofNullable(url);
163 }
164
165 public static <T> T createInternalObject(String type) {
166 T answer;
167
168 try {
169 Class<T> clazz = internalClassForName(type);
170 answer = clazz.getConstructor().newInstance();
171 } catch (Exception e) {
172 throw new InternalException(getString("RuntimeError.6", type), e);
173 }
174
175 return answer;
176 }
177
178 public static JavaTypeResolver createJavaTypeResolver(Context context, List<String> warnings) {
179 String type = context.getJavaTypeResolverConfiguration()
180 .map(JavaTypeResolverConfiguration::getImplementationType)
181 .orElse(Defaults.DEFAULT_JAVA_TYPE_RESOLVER);
182
183 JavaTypeResolver answer = createInternalObject(type);
184 answer.setWarnings(warnings);
185
186 context.getJavaTypeResolverConfiguration()
187 .ifPresent(c -> answer.addConfigurationProperties(c.getProperties()));
188
189 answer.setContext(context);
190
191 return answer;
192 }
193
194 public static Plugin createPlugin(Context context, PluginConfiguration pluginConfiguration,
195 CommentGenerator commentGenerator, KnownRuntime knownRuntime) {
196 Plugin plugin = createInternalObject(pluginConfiguration.getConfigurationType().orElseThrow());
197 plugin.setContext(context);
198 plugin.setProperties(pluginConfiguration.getProperties());
199 plugin.setCommentGenerator(commentGenerator);
200 plugin.setKnownRuntime(knownRuntime);
201 return plugin;
202 }
203
204 public static CommentGenerator createCommentGenerator(Context context) {
205 CommentGenerator answer;
206
207 String type = context.getCommentGeneratorConfiguration()
208 .map(CommentGeneratorConfiguration::getImplementationType)
209 .orElse(Defaults.DEFAULT_COMMENT_GENERATOR);
210
211 answer = createInternalObject(type);
212
213 context.getCommentGeneratorConfiguration()
214 .ifPresent(c -> answer.addConfigurationProperties(c.getProperties()));
215
216 return answer;
217 }
218
219 public static ConnectionFactory createConnectionFactory(ConnectionFactoryConfiguration config) {
220 ConnectionFactory answer;
221
222 String type = config.getImplementationType();
223
224 answer = createInternalObject(type);
225 answer.addConfigurationProperties(config.getProperties());
226
227 return answer;
228 }
229
230 public static JavaFormatter createJavaFormatter(Context context) {
231 String type = stringValueOrElse(context.getProperty(PropertyRegistry.CONTEXT_JAVA_FORMATTER),
232 Defaults.DEFAULT_JAVA_FORMATTER);
233 JavaFormatter answer = createInternalObject(type);
234
235 answer.setContext(context);
236
237 return answer;
238 }
239
240 public static KotlinFormatter createKotlinFormatter(Context context) {
241 String type = stringValueOrElse(context.getProperty(PropertyRegistry.CONTEXT_KOTLIN_FORMATTER),
242 Defaults.DEFAULT_KOTLIN_FORMATTER);
243 KotlinFormatter answer = createInternalObject(type);
244
245 answer.setContext(context);
246
247 return answer;
248 }
249
250 public static XmlFormatter createXmlFormatter(Context context) {
251 String type = stringValueOrElse(context.getProperty(PropertyRegistry.CONTEXT_XML_FORMATTER),
252 Defaults.DEFAULT_XML_FORMATTER);
253 XmlFormatter answer = createInternalObject(type);
254
255 answer.setContext(context);
256
257 return answer;
258 }
259
260 public static IntrospectedColumn createIntrospectedColumn(Context context) {
261 String type = context.getIntrospectedColumnImpl().orElse(IntrospectedColumn.class.getName());
262 IntrospectedColumn answer = createInternalObject(type);
263 answer.setContext(context);
264
265 return answer;
266 }
267 }