Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.github.jinahya.database.metadata.bind;
/*-
* #%L
* database-metadata-bind
* %%
* Copyright (C) 2011 - 2019 Jinahya, Inc.
* %%
* 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
*
* http://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.
* #L%
*/
import lombok.NonNull;
import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
import static com.github.jinahya.database.metadata.bind.Invokes.arguments;
import static com.github.jinahya.database.metadata.bind.Utils.field;
import static com.github.jinahya.database.metadata.bind.Utils.fields;
import static com.github.jinahya.database.metadata.bind.Utils.labels;
import static com.github.jinahya.database.metadata.bind.Utils.suppressionPath;
import static java.lang.String.format;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.SEVERE;
import static java.util.logging.Logger.getLogger;
/**
* A context class for retrieving information from an instance of {@link java.sql.DatabaseMetaData}.
*
* @author Jin Kwon <jinahya_at_gmail.com>
*/
public class MetadataContext {
// -----------------------------------------------------------------------------------------------------------------
private static final Logger logger = getLogger(MetadataContext.class.getName());
// -----------------------------------------------------------------------------------------------------------------
/**
* Invokes {@link #getSchemas(java.lang.String, java.lang.String)} on given {@code context} with given {@code
* catalog}.
*
* @param context the context
* @param catalog the value for the first parameter of {@link #getSchemas(java.lang.String, java.lang.String)}.
* @param nonempty a flag for non empty
* @return a list of schemas
* @throws SQLException if a database error occurs.
*/
public static List getSchemas(@NonNull final MetadataContext context, final String catalog,
final boolean nonempty)
throws SQLException {
final List schemas = context.getSchemas(catalog, null);
if (schemas.isEmpty() && nonempty) {
final Schema schema = new Schema();
schema.virtual = true;
schema.setTableCatalog(catalog);
schema.setTableSchem("");
if (!context.isSuppressionPath("schema/functions")) {
schema.getFunctions().addAll(context.getFunctions(
schema.getTableCatalog(), schema.getTableSchem(), null));
}
if (!context.isSuppressionPath("schema/procedures")) {
schema.getProcedures().addAll(context.getProcedures(
schema.getTableCatalog(), schema.getTableSchem(), null));
}
if (!context.isSuppressionPath("schema/tables")) {
schema.getTables().addAll(context.getTables(
schema.getTableCatalog(), schema.getTableSchem(), null, null));
}
if (!context.isSuppressionPath("schema/UDTs")) {
schema.getUDTs().addAll(context.getUDTs(
schema.getTableCatalog(), schema.getTableSchem(), null, null));
}
schemas.add(schema);
}
return schemas;
}
public static List getSchemas(@NonNull final MetadataContext context, final String catalog)
throws SQLException {
return getSchemas(context, catalog, false);
}
/**
* Invokes {@link #getCatalogs()} on given context.
*
* @param context the context
* @param nonempty a flag for adding a virtual instances if non retrieved.
* @return a list of catalogs
* @throws SQLException if a database error occurs.
*/
public static List getCatalogs(@NonNull final MetadataContext context, final boolean nonempty)
throws SQLException {
final List catalogs = context.getCatalogs();
if (catalogs.isEmpty() && nonempty) {
final Catalog catalog = new Catalog();
catalog.virtual = true;
catalog.setTableCat("");
catalogs.add(catalog);
if (!context.isSuppressionPath("catalog/schemas")) {
catalog.getSchemas().addAll(context.getSchemas(catalog.getTableCat(), ""));
}
}
if (!context.isSuppressionPath("catalog/schemas")) {
boolean allempty = true;
for (final Catalog catalog : catalogs) {
if (!catalog.getSchemas().isEmpty()) {
allempty = false;
break;
}
}
if (allempty) {
logger.warning("schemas are all empty");
for (final Catalog catalog : catalogs) {
catalog.getSchemas().addAll(getSchemas(context, catalog.getTableCat(), true));
}
}
}
return catalogs;
}
public static List getCatalogs(@NonNull final MetadataContext context) throws SQLException {
return getCatalogs(context, false);
}
// -----------------------------------------------------------------------------------------------------------------
/**
* Creates a new instance with given instance of {@link DatabaseMetaData}.
*
* @param metadata the {@link DatabaseMetaData} instance to hold.
*/
public MetadataContext(final DatabaseMetaData metadata) {
super();
this.databaseMetadata = requireNonNull(metadata, "databaseMetadata is null");
}
// -----------------------------------------------------------------------------------------------------------------
/**
* Binds given instance from specified record.
*
* @param instance type parameter
* @param results the result set from which the instance is bound
* @param type the type of the instance
* @param instance the instance
* @return given instance
* @throws SQLException if a database error occurs.
*/
private T bind(final ResultSet results, final Class type, final T instance) throws SQLException {
final Set labels = labels(results);
for (final Entry bfield : bfields(type).entrySet()) {
final Field field = bfield.getKey();
final Bind bind = bfield.getValue();
String label = bind.label();
final String path = suppressionPath(type, field);
if (isSuppressionPath(path)) {
continue;
}
final String formatted = format("field=%s, suppressionPath=%s, bind=%s", field, path, bind);
if (!labels.remove(label)) {
logger.warning(format("unknown label; %s", formatted));
continue;
}
if (bind.unused()) {
continue;
}
final Object value = results.getObject(label);
if (value == null) {
if (!bind.nillable() && !bind.unused() && !bind.reserved()) {
logger.warning(format("null value; %s", formatted));
}
if (field.getType().isPrimitive()) {
logger.warning(format("null value; %s", formatted));
}
}
try {
field(field, instance, results, label);
} catch (final ReflectiveOperationException roe) {
logger.log(SEVERE, format("failed to set %s with %s on %s", field, value, instance), roe);
}
}
for (String label : labels) {
final Object value = results.getObject(label);
if (logger.isLoggable(FINE)) {
logger.fine(format("unhandled; klass=%s, label=%s, value=%s", type, label, value));
}
}
for (final Entry ifield : ifields(type).entrySet()) {
final Field field = ifield.getKey();
if (!field.getType().equals(List.class)) {
logger.severe(format("wrong field type: %s", field.getType()));
continue;
}
final Invoke invoke = ifield.getValue();
final String path = Utils.suppressionPath(type, field);
final String formatted = format("field=%s, suppressionPath=%s, invoke=%s", field, path, invoke);
if (isSuppressionPath(path)) {
if (logger.isLoggable(FINE)) {
logger.fine(format("skipping; %s", formatted));
}
continue;
}
final String name = invoke.name();
final Class>[] types = invoke.types();
final Method method;
try {
method = DatabaseMetaData.class.getMethod(name, types);
} catch (final NoSuchMethodException nsme) {
logger.log(SEVERE, format("unknown method; %1$s", formatted), nsme);
continue;
} catch (final NoSuchMethodError nsme) {
logger.log(SEVERE, format("unknown method; %s", formatted), nsme);
continue;
}
final List