All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.anwiba.commons.swing.database.console.tree.SchemaTreeFactory Maven / Gradle / Ivy

There is a newer version: 1.0.185
Show newest version
/*
 * #%L
 * *
 * %%
 * Copyright (C) 2007 - 2017 Andreas W. Bartels
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 2.1 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */
package net.anwiba.commons.swing.database.console.tree;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;

import net.anwiba.commons.jdbc.connection.IJdbcConnectionDescription;
import net.anwiba.commons.jdbc.database.IDatabaseFacade;
import net.anwiba.commons.jdbc.database.INamedTableFilter;
import net.anwiba.commons.jdbc.name.DatabaseTableName;
import net.anwiba.commons.jdbc.name.IDatabaseConstraintName;
import net.anwiba.commons.jdbc.name.IDatabaseIndexName;
import net.anwiba.commons.jdbc.name.IDatabaseSequenceName;
import net.anwiba.commons.jdbc.name.IDatabaseTableName;
import net.anwiba.commons.jdbc.name.IDatabaseTriggerName;
import net.anwiba.commons.lang.functional.IClosure;
import net.anwiba.commons.logging.ILevel;
import net.anwiba.commons.model.IBooleanModel;
import net.anwiba.commons.model.IObjectModel;
import net.anwiba.commons.swing.database.console.SqlConsoleMessages;
import net.anwiba.commons.swing.tree.LazyFolderTreeNode;

public final class SchemaTreeFactory {

  private static net.anwiba.commons.logging.ILogger logger = net.anwiba.commons.logging.Logging
      .getLogger(SchemaTreeFactory.class);
  private final IDatabaseFacade databaseFacade;
  private final IObjectModel connectionModel;
  private final IObjectModel statusModel;
  private final IBooleanModel isDisconnectedModel;
  private final IBooleanModel isConnectedModel;

  public SchemaTreeFactory(
      final IDatabaseFacade databaseFacade,
      final IObjectModel connectionModel,
      final IObjectModel statusModel,
      final IBooleanModel isDisconnectedModel,
      final IBooleanModel isConnectedModel) {
    this.databaseFacade = databaseFacade;
    this.connectionModel = connectionModel;
    this.statusModel = statusModel;
    this.isDisconnectedModel = isDisconnectedModel;
    this.isConnectedModel = isConnectedModel;
  }

  @SuppressWarnings("resource")
  public DefaultMutableTreeNode create(final IJdbcConnectionDescription description, final String schema) {
    this.statusModel.set(SqlConsoleMessages.working);
    final DefaultMutableTreeNode root = new DefaultMutableTreeNode(description.getUrl());
    try {
      final Connection connection = this.connectionModel.get();
      final boolean isClosed = connection.isClosed();
      if (isClosed) {
        this.isConnectedModel.set(!isClosed);
        this.isDisconnectedModel.set(isClosed);
        this.statusModel.set(SqlConsoleMessages.connectionIsClosed);
        return root;
      }
      final String catalog = getCatalog();
      final Set schemaNames = new HashSet<>(this.databaseFacade.getSchemaNames(connection, catalog));
      final DatabaseMetaData metaData = connection.getMetaData();
      final Map schemas = new LinkedHashMap<>();
      if (schema != null) {
        addSchema(connection, metaData, root, catalog, schema, schemas);
      } else {
        try (final ResultSet resultSet = metaData.getSchemas()) {
          while (resultSet.next()) {
            final String schemaName = resultSet.getString(1);
            if (!schemaNames.contains(schemaName)) {
              continue;
            }
            addSchema(connection, metaData, root, catalog, schemaName, schemas);
          }
        }
      }
      if (schemas.isEmpty()) {
        addSchema(connection, metaData, root, catalog, schema, schemas);
      }
      this.statusModel.set(SqlConsoleMessages.done);
      return root;
    } catch (final SQLException exception) {
      logger.log(ILevel.DEBUG, exception.getMessage(), exception);
      this.statusModel.set(exception.getMessage());
      return root;
    }
  }

  private void addSchema(
      final Connection connection,
      final DatabaseMetaData metaData,
      final DefaultMutableTreeNode root,
      final String catalog,
      final String schemaName,
      final Map schemas) {
    final DefaultMutableTreeNode schemaNode = schemaName == null ? root : new DefaultMutableTreeNode(schemaName);
    schemaNode.add(createTablesNode(connection, metaData, catalog, schemaName));
    schemaNode.add(createViewsNode(metaData, catalog, schemaName));
    if (this.databaseFacade.supportsSequences()) {
      schemaNode.add(createSequencesNode(connection, schemaName));
    }
    for (final INamedTableFilter filter : this.databaseFacade.getTableFilters()) {
      schemaNode.add(createOtherNodes(connection, metaData, catalog, schemaName, filter));
    }
    if (schemaName != null) {
      root.add(schemaNode);
    }
    schemas.put(schemaName, schemaNode);
  }

  private LazyFolderTreeNode createSequencesNode(final Connection connection, final String schemaName) {
    return new LazyFolderTreeNode(
        SqlConsoleMessages.sequences,
        new IClosure, RuntimeException>() {

          @Override
          public List execute() throws RuntimeException {
            try {
              final List sequences = SchemaTreeFactory.this.databaseFacade
                  .getSequences(connection, schemaName);
              final List nodes = new ArrayList<>();
              for (final IDatabaseSequenceName sequence : sequences) {
                nodes.add(new DefaultMutableTreeNode(sequence));
              }
              return nodes;
            } catch (final Exception exception) {
              return Collections.emptyList();
            }
          }
        });
  }

  private LazyFolderTreeNode createViewsNode(
      final DatabaseMetaData metaData,
      final String catalog,
      final String schemaName) {
    return new LazyFolderTreeNode(
        SqlConsoleMessages.views,
        new IClosure, RuntimeException>() {

          @Override
          public List execute() throws RuntimeException {
            try (final ResultSet tablesResultSet = metaData
                .getTables(catalog, schemaName, null, new String[]{ "VIEW" })) { //$NON-NLS-1$
              final List nodes = new ArrayList<>();
              while (tablesResultSet.next()) {
                final String schema = tablesResultSet.getString(2);
                final String name = tablesResultSet.getString(3);
                final IDatabaseTableName table = new DatabaseTableName(schema, name);
                nodes.add(new DefaultMutableTreeNode(table));
              }
              return nodes;
            } catch (final Exception exception) {
              return Collections.emptyList();
            }
          }
        });
  }

  private LazyFolderTreeNode createTablesNode(
      final Connection connection,
      final DatabaseMetaData metaData,
      final String catalog,
      final String schemaName) {
    return new LazyFolderTreeNode(
        SqlConsoleMessages.tables,
        new IClosure, RuntimeException>() {

          @Override
          public List execute() throws RuntimeException {
            try (final ResultSet tablesResultSet = metaData
                .getTables(catalog, schemaName, null, new String[]{ "TABLE" })) { //$NON-NLS-1$
              final List nodes = new ArrayList<>();
              while (tablesResultSet.next()) {
                final String schema = tablesResultSet.getString(2);
                final String name = tablesResultSet.getString(3);
                final IDatabaseTableName table = new DatabaseTableName(schema, name);
                if (!SchemaTreeFactory.this.databaseFacade.isTable(table)) {
                  continue;
                }
                final DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(table);
                if (SchemaTreeFactory.this.databaseFacade.supportsConstaints()) {
                  tableNode.add(createConstraintsNode(connection, table));
                }
                if (SchemaTreeFactory.this.databaseFacade.supportsIndicies()) {
                  tableNode.add(createIndiciesNode(connection, table));
                }
                if (SchemaTreeFactory.this.databaseFacade.supportsTrigger()) {
                  tableNode.add(createTriggersNode(connection, table));
                }
                nodes.add(tableNode);
              }
              return nodes;
            } catch (final Exception exception) {
              return Collections.emptyList();
            }
          }
        });
  }

  private LazyFolderTreeNode createOtherNodes(
      final Connection connection,
      final DatabaseMetaData metaData,
      final String catalog,
      final String schemaName,
      final INamedTableFilter filter) {
    return new LazyFolderTreeNode(filter.getName(), new IClosure, RuntimeException>() {

      @Override
      public List execute() throws RuntimeException {
        try (final ResultSet tablesResultSet = metaData.getTables(catalog, schemaName, null, new String[]{ "TABLE" })) { //$NON-NLS-1$
          final List nodes = new ArrayList<>();
          while (tablesResultSet.next()) {
            final String schema = tablesResultSet.getString(2);
            final String name = tablesResultSet.getString(3);
            final IDatabaseTableName table = new DatabaseTableName(schema, name);
            if (!filter.accept(table)) {
              continue;
            }
            final DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(table);
            if (SchemaTreeFactory.this.databaseFacade.supportsConstaints()) {
              tableNode.add(createConstraintsNode(connection, table));
            }
            if (SchemaTreeFactory.this.databaseFacade.supportsIndicies()) {
              tableNode.add(createIndiciesNode(connection, table));
            }
            if (SchemaTreeFactory.this.databaseFacade.supportsTrigger()) {
              tableNode.add(createTriggersNode(connection, table));
            }
            nodes.add(tableNode);
          }
          return nodes;
        } catch (final Exception exception) {
          return Collections.emptyList();
        }
      }
    });
  }

  private MutableTreeNode createIndiciesNode(final Connection connection, final IDatabaseTableName table) {
    return new LazyFolderTreeNode(
        SqlConsoleMessages.indicies,
        new IClosure, RuntimeException>() {

          @Override
          public List execute() throws RuntimeException {
            try {
              final List names = SchemaTreeFactory.this.databaseFacade
                  .getIndicies(connection, table);
              final List nodes = new ArrayList<>();
              for (final IDatabaseIndexName name : names) {
                nodes.add(new DefaultMutableTreeNode(name));
              }
              return nodes;
            } catch (final Exception exception) {
              return Collections.emptyList();
            }
          }
        });
  }

  private MutableTreeNode createTriggersNode(final Connection connection, final IDatabaseTableName table) {
    return new LazyFolderTreeNode(
        SqlConsoleMessages.triggers,
        new IClosure, RuntimeException>() {

          @Override
          public List execute() throws RuntimeException {
            try {
              final List names = SchemaTreeFactory.this.databaseFacade
                  .getTriggers(connection, table);
              final List nodes = new ArrayList<>();
              for (final IDatabaseTriggerName name : names) {
                nodes.add(new DefaultMutableTreeNode(name));
              }
              return nodes;
            } catch (final Exception exception) {
              return Collections.emptyList();
            }
          }
        });
  }

  private MutableTreeNode createConstraintsNode(final Connection connection, final IDatabaseTableName tableName) {
    return new LazyFolderTreeNode(
        SqlConsoleMessages.constraints,
        new IClosure, RuntimeException>() {

          @Override
          public List execute() throws RuntimeException {
            try {
              final List names = SchemaTreeFactory.this.databaseFacade
                  .getConstraints(connection, tableName);
              final List nodes = new ArrayList<>();
              for (final IDatabaseConstraintName name : names) {
                nodes.add(new DefaultMutableTreeNode(name));
              }
              return nodes;
            } catch (final Exception exception) {
              return Collections.emptyList();
            }
          }
        });
  }

  private String getCatalog() {
    try {
      return this.connectionModel.get().getCatalog();
    } catch (final AbstractMethodError | Exception exception) {
      return null;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy