1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.generator.api;
17
18 import static org.mybatis.generator.internal.util.StringUtility.composeFullyQualifiedTableName;
19 import static org.mybatis.generator.internal.util.StringUtility.mapStringValueOrElseGet;
20 import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
21 import static org.mybatis.generator.internal.util.StringUtility.stringValueOrElseGet;
22
23 import java.util.Objects;
24 import java.util.Optional;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import org.jspecify.annotations.Nullable;
29 import org.mybatis.generator.config.Context;
30 import org.mybatis.generator.config.DomainObjectRenamingRule;
31 import org.mybatis.generator.internal.util.JavaBeansUtil;
32
33 public class FullyQualifiedTable {
34 private final @Nullable String introspectedCatalog;
35 private final @Nullable String introspectedSchema;
36 private final String introspectedTableName;
37 private final @Nullable String runtimeCatalog;
38 private final @Nullable String runtimeSchema;
39 private final @Nullable String runtimeTableName;
40 private @Nullable String configuredDomainObjectName;
41 private @Nullable String domainObjectSubPackage;
42 private final @Nullable String alias;
43 private final boolean ignoreQualifiersAtRuntime;
44 private final String beginningDelimiter;
45 private final String endingDelimiter;
46 private final @Nullable DomainObjectRenamingRule domainObjectRenamingRule;
47
48 public FullyQualifiedTable(Builder builder) {
49 introspectedCatalog = builder.introspectedCatalog;
50 introspectedSchema = builder.introspectedSchema;
51 introspectedTableName = Objects.requireNonNull(builder.introspectedTableName);
52 ignoreQualifiersAtRuntime = builder.ignoreQualifiersAtRuntime;
53 runtimeCatalog = builder.runtimeCatalog;
54 runtimeSchema = builder.runtimeSchema;
55 runtimeTableName = builder.runtimeTableName;
56 domainObjectRenamingRule = builder.domainObjectRenamingRule;
57
58 if (stringHasValue(builder.domainObjectName)) {
59 int index = builder.domainObjectName.lastIndexOf('.');
60 if (index == -1) {
61 configuredDomainObjectName = builder.domainObjectName;
62 } else {
63 configuredDomainObjectName = builder.domainObjectName.substring(index + 1);
64 domainObjectSubPackage = builder.domainObjectName.substring(0, index);
65 }
66 }
67
68 if (builder.alias == null) {
69 alias = null;
70 } else {
71 this.alias = builder.alias.trim();
72 }
73
74 if (builder.delimitIdentifiers && builder.context != null) {
75 beginningDelimiter = builder.context.getBeginningDelimiter();
76 endingDelimiter = builder.context.getEndingDelimiter();
77 } else {
78 beginningDelimiter = "";
79 endingDelimiter = "";
80
81 }
82 }
83
84 public Optional<String> getIntrospectedCatalog() {
85 return Optional.ofNullable(introspectedCatalog);
86 }
87
88 public Optional<String> getIntrospectedSchema() {
89 return Optional.ofNullable(introspectedSchema);
90 }
91
92 public String getIntrospectedTableName() {
93 return introspectedTableName;
94 }
95
96 public String getFullyQualifiedTableNameAtRuntime() {
97 StringBuilder localCatalog = new StringBuilder();
98 if (!ignoreQualifiersAtRuntime) {
99 if (stringHasValue(runtimeCatalog)) {
100 localCatalog.append(runtimeCatalog);
101 } else if (stringHasValue(introspectedCatalog)) {
102 localCatalog.append(introspectedCatalog);
103 }
104 }
105 if (!localCatalog.isEmpty()) {
106 addDelimiters(localCatalog);
107 }
108
109 StringBuilder localSchema = new StringBuilder();
110 if (!ignoreQualifiersAtRuntime) {
111 if (stringHasValue(runtimeSchema)) {
112 localSchema.append(runtimeSchema);
113 } else if (stringHasValue(introspectedSchema)) {
114 localSchema.append(introspectedSchema);
115 }
116 }
117 if (!localSchema.isEmpty()) {
118 addDelimiters(localSchema);
119 }
120
121 StringBuilder localTableName = new StringBuilder();
122 if (stringHasValue(runtimeTableName)) {
123 localTableName.append(runtimeTableName);
124 } else {
125 localTableName.append(introspectedTableName);
126 }
127 addDelimiters(localTableName);
128
129 return composeFullyQualifiedTableName(localCatalog.toString(), localSchema.toString(),
130 localTableName.toString(), '.');
131 }
132
133 public String getAliasedFullyQualifiedTableNameAtRuntime() {
134 StringBuilder sb = new StringBuilder();
135
136 sb.append(getFullyQualifiedTableNameAtRuntime());
137
138 if (stringHasValue(alias)) {
139 sb.append(' ');
140 sb.append(alias);
141 }
142
143 return sb.toString();
144 }
145
146 public String getDomainObjectName() {
147 return stringValueOrElseGet(configuredDomainObjectName, this::calculateDomainObjectName);
148 }
149
150 private String calculateDomainObjectName() {
151 String finalDomainObjectName = mapStringValueOrElseGet(runtimeTableName,
152 s -> JavaBeansUtil.getCamelCaseString(s, true),
153 () -> JavaBeansUtil.getCamelCaseString(introspectedTableName, true));
154
155 if (domainObjectRenamingRule != null) {
156 Pattern pattern = domainObjectRenamingRule.pattern();
157 String replaceString = domainObjectRenamingRule.replaceString();
158 Matcher matcher = pattern.matcher(finalDomainObjectName);
159 finalDomainObjectName = JavaBeansUtil.getFirstCharacterUppercase(matcher.replaceAll(replaceString));
160 }
161 return finalDomainObjectName;
162 }
163
164 @Override
165 public boolean equals(Object obj) {
166 if (this == obj) {
167 return true;
168 }
169
170 if (!(obj instanceof FullyQualifiedTable other)) {
171 return false;
172 }
173
174 return Objects.equals(this.introspectedTableName, other.introspectedTableName)
175 && Objects.equals(this.introspectedCatalog, other.introspectedCatalog)
176 && Objects.equals(this.introspectedSchema, other.introspectedSchema);
177 }
178
179 @Override
180 public int hashCode() {
181 return Objects.hash(introspectedTableName, introspectedCatalog, introspectedCatalog);
182 }
183
184 @Override
185 public String toString() {
186 return composeFullyQualifiedTableName(
187 introspectedCatalog, introspectedSchema, introspectedTableName,
188 '.');
189 }
190
191 public Optional<String> getAlias() {
192 return Optional.ofNullable(alias);
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207 public String getSubPackageForClientOrSqlMap(boolean isSubPackagesEnabled) {
208 StringBuilder sb = new StringBuilder();
209 if (!ignoreQualifiersAtRuntime && isSubPackagesEnabled) {
210 if (stringHasValue(runtimeCatalog)) {
211 sb.append('.');
212 sb.append(runtimeCatalog.toLowerCase());
213 } else if (stringHasValue(introspectedCatalog)) {
214 sb.append('.');
215 sb.append(introspectedCatalog.toLowerCase());
216 }
217
218 if (stringHasValue(runtimeSchema)) {
219 sb.append('.');
220 sb.append(runtimeSchema.toLowerCase());
221 } else if (stringHasValue(introspectedSchema)) {
222 sb.append('.');
223 sb.append(introspectedSchema.toLowerCase());
224 }
225 }
226
227
228 return sb.toString();
229 }
230
231
232
233
234
235
236
237
238
239
240
241
242
243 public String getSubPackageForModel(boolean isSubPackagesEnabled) {
244 StringBuilder sb = new StringBuilder();
245 sb.append(getSubPackageForClientOrSqlMap(isSubPackagesEnabled));
246
247 if (stringHasValue(domainObjectSubPackage)) {
248 sb.append('.');
249 sb.append(domainObjectSubPackage);
250 }
251
252 return sb.toString();
253 }
254
255 private void addDelimiters(StringBuilder sb) {
256 if (stringHasValue(beginningDelimiter)) {
257 sb.insert(0, beginningDelimiter);
258 }
259
260 if (stringHasValue(endingDelimiter)) {
261 sb.append(endingDelimiter);
262 }
263 }
264
265 public Optional<String> getDomainObjectSubPackage() {
266 return Optional.ofNullable(domainObjectSubPackage);
267 }
268
269 public static class Builder {
270 private @Nullable String introspectedCatalog;
271 private @Nullable String introspectedSchema;
272 private @Nullable String introspectedTableName;
273 private @Nullable String runtimeCatalog;
274 private @Nullable String runtimeSchema;
275 private @Nullable String runtimeTableName;
276 private @Nullable String domainObjectName;
277 private @Nullable String alias;
278 private boolean ignoreQualifiersAtRuntime;
279 private boolean delimitIdentifiers;
280 private @Nullable DomainObjectRenamingRule domainObjectRenamingRule;
281 private @Nullable Context context;
282
283
284
285
286
287
288
289
290
291
292 public Builder withIntrospectedCatalog(@Nullable String introspectedCatalog) {
293 this.introspectedCatalog = introspectedCatalog;
294 return this;
295 }
296
297
298
299
300
301
302
303
304
305
306 public Builder withIntrospectedSchema(@Nullable String introspectedSchema) {
307 this.introspectedSchema = introspectedSchema;
308 return this;
309 }
310
311
312
313
314
315
316
317 public Builder withIntrospectedTableName(String introspectedTableName) {
318 this.introspectedTableName = introspectedTableName;
319 return this;
320 }
321
322
323
324
325
326
327
328
329
330
331 public Builder withRuntimeCatalog(@Nullable String runtimeCatalog) {
332 this.runtimeCatalog = runtimeCatalog;
333 return this;
334 }
335
336
337
338
339
340
341
342
343
344
345 public Builder withRuntimeSchema(@Nullable String runtimeSchema) {
346 this.runtimeSchema = runtimeSchema;
347 return this;
348 }
349
350
351
352
353
354
355
356
357
358
359
360 public Builder withRuntimeTableName(@Nullable String runtimeTableName) {
361 this.runtimeTableName = runtimeTableName;
362 return this;
363 }
364
365
366
367
368
369
370
371
372
373 public Builder withDomainObjectName(@Nullable String domainObjectName) {
374 this.domainObjectName = domainObjectName;
375 return this;
376 }
377
378
379
380
381
382
383
384 public Builder withAlias(@Nullable String alias) {
385 this.alias = alias;
386 return this;
387 }
388
389
390
391
392
393
394
395
396
397
398
399 public Builder withIgnoreQualifiersAtRuntime(boolean ignoreQualifiersAtRuntime) {
400 this.ignoreQualifiersAtRuntime = ignoreQualifiersAtRuntime;
401 return this;
402 }
403
404
405
406
407
408
409
410
411
412 public Builder withDelimitIdentifiers(boolean delimitIdentifiers) {
413 this.delimitIdentifiers = delimitIdentifiers;
414 return this;
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429 public Builder withDomainObjectRenamingRule(@Nullable DomainObjectRenamingRule domainObjectRenamingRule) {
430 this.domainObjectRenamingRule = domainObjectRenamingRule;
431 return this;
432 }
433
434 public Builder withContext(Context context) {
435 this.context = context;
436 return this;
437 }
438
439 public FullyQualifiedTable build() {
440 return new FullyQualifiedTable(this);
441 }
442 }
443 }