IntrospectionEngine.java
/*
* Copyright 2006-2026 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mybatis.generator.codegen;
import static org.mybatis.generator.internal.util.messages.Messages.getString;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.jspecify.annotations.Nullable;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.ProgressCallback;
import org.mybatis.generator.config.TableConfiguration;
import org.mybatis.generator.internal.ObjectFactory;
import org.mybatis.generator.internal.db.DatabaseIntrospector;
public class IntrospectionEngine {
private final CalculatedContextValues contextValues;
private final ProgressCallback progressCallback;
private final List<String> warnings;
private final Set<String> fullyQualifiedTableNames;
protected IntrospectionEngine(Builder builder) {
contextValues = Objects.requireNonNull(builder.contextValues);
progressCallback = Objects.requireNonNull(builder.progressCallback);
warnings = Objects.requireNonNull(builder.warnings);
fullyQualifiedTableNames = Objects.requireNonNull(builder.fullyQualifiedTableNames);
}
/**
* Introspect tables based on the configuration specified in the
* constructor. This method is long-running.
*
* @return a list containing the results of table introspection. The list will be empty
* if this method is called before introspectTables(), or if no tables are found that
* match the configuration
*
* @throws java.sql.SQLException
* if some error arises while introspecting the specified
* database tables.
* @throws InterruptedException
* if the progress callback reports a cancel
*/
public List<IntrospectedTable> introspectTables()
throws SQLException, InterruptedException {
List<IntrospectedTable> introspectedTables = new ArrayList<>();
JavaTypeResolver javaTypeResolver = ObjectFactory.createJavaTypeResolver(contextValues.context(), warnings);
try (Connection connection = ConnectionUtility.getConnection(contextValues.context())) {
progressCallback.startTask(getString("Progress.0")); //$NON-NLS-1$
DatabaseIntrospector databaseIntrospector = new DatabaseIntrospector(
contextValues.context(), connection.getMetaData(), javaTypeResolver);
for (TableConfiguration tc : contextValues.context().tableConfigurations()) {
if (!shouldIntrospect(tc)) {
continue;
}
progressCallback.startTask(getString("Progress.1", tc.getFullyQualifiedName())); //$NON-NLS-1$
List<IntrospectedTable> tables = databaseIntrospector
.introspectTables(tc, contextValues.knownRuntime(), contextValues.pluginAggregator());
introspectedTables.addAll(tables);
progressCallback.checkCancel();
}
warnings.addAll(databaseIntrospector.getWarnings());
}
return introspectedTables;
}
private boolean shouldIntrospect(TableConfiguration tc) {
if (isTableExcluded(tc.getFullyQualifiedName())) {
return false;
}
if (contextValues.knownRuntime().isLegacyMyBatis3Based() && !tc.areAnyStatementsEnabled()) {
warnings.add(getString("Warning.0", tc.getFullyQualifiedName())); //$NON-NLS-1$
return false;
}
return true;
}
private boolean isTableExcluded(String tableName) {
return !isTableIncluded(tableName);
}
private boolean isTableIncluded(String tableName) {
if (fullyQualifiedTableNames.isEmpty()) {
return true;
}
return fullyQualifiedTableNames.contains(tableName);
}
public static class Builder {
private @Nullable CalculatedContextValues contextValues;
private @Nullable ProgressCallback progressCallback;
private @Nullable List<String> warnings;
private @Nullable Set<String> fullyQualifiedTableNames;
public Builder withContextValues(CalculatedContextValues contextValues) {
this.contextValues = contextValues;
return this;
}
public Builder withProgressCallback(ProgressCallback progressCallback) {
this.progressCallback = progressCallback;
return this;
}
public Builder withWarnings(List<String> warnings) {
this.warnings = warnings;
return this;
}
/**
* Sets a Set of table names for introspection.
*
* @param fullyQualifiedTableNames
* a set of table names to introspect. The elements of the set must
* be Strings that exactly match what's specified in the
* configuration. For example, if a table name is "foo" and the schema is
* "bar", then the fully qualified table name is "foo.bar". If
* the Set is empty, then all tables in the configuration
* will be used for code generation.
*
*
* @return this builder
*/
public Builder withFullyQualifiedTableNames(Set<String> fullyQualifiedTableNames) {
this.fullyQualifiedTableNames = fullyQualifiedTableNames;
return this;
}
public IntrospectionEngine build() {
return new IntrospectionEngine(this);
}
}
}