/* * Copyright (C) 2006 Davy Vanherbergen * dvanherbergen@users.sourceforge.net * * 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 library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sourceforge.sqlexplorer.dbstructure.nodes; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.sourceforge.sqlexplorer.Messages; import net.sourceforge.sqlexplorer.dbproduct.MetaDataSession; import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin; import net.sourceforge.sqlexplorer.util.TextUtil; import net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; /** * Root node for a database. ChildNodes can be filtered based on expressions in * the alias. * * @author Davy Vanherbergen */ public class DatabaseNode extends AbstractNode { private List _childNames = new ArrayList(); private String _databaseProductName = ""; private String[] _filterExpressions; private boolean _supportsCatalogs = false; private boolean _supportsSchemas = false; private String _databaseVersion = ""; /** * Create a new database node with the given name * * @param name * @param alias */ public DatabaseNode(String name, MetaDataSession session) throws SQLException { super(name, session); setImageKey("Images.DatabaseIcon"); try { SQLDatabaseMetaData metadata = _session.getMetaData(); if (metadata.supportsCatalogs()) { _supportsCatalogs = true; } if (metadata.supportsSchemas()) { _supportsSchemas = true; } _databaseProductName = metadata.getDatabaseProductName(); try { // MOD scorreia 2008-10-23 surround with try/catch to caught error when the getDatabaseMajorVersion() // method is not implemented by the driver (e.g. for sybase). _databaseVersion = " [v" + metadata.getJDBCMetaData().getDatabaseMajorVersion() + "." + metadata.getJDBCMetaData().getDatabaseMinorVersion() + "]"; } catch (Exception e) { // MOD yyi 17143 2010-12-03 remove the error message of Cannot get database version // SQLExplorerPlugin.error("Cannot get database version", e); // 17143 _databaseVersion = " undefined "; } } catch (AbstractMethodError e) { SQLExplorerPlugin.error("Error loading database product name.", e); } } /** * @return List of catalog nodes */ public List getCatalogs() { ArrayList catalogs = new ArrayList(); Iterator it = getChildIterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof CatalogNode) { catalogs.add(o); } } return catalogs; } public String[] getChildNames() { if (_childNames.size() == 0) { getChildNodes(); } return (String[]) _childNames.toArray(new String[] {}); } public String getDatabaseProductName() { return _databaseProductName; } /* * (non-Javadoc) * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#getLabelText() */ public String getLabelText() { if (_session.getUser().getAlias().isFiltered()) { return _databaseProductName + " " + _databaseVersion + " " + Messages.getString("DatabaseStructureView.filteredPostfix"); } else { return _databaseProductName + " " + _databaseVersion; } } /** * @return List of all database schemas */ public List getSchemas() { ArrayList schemas = new ArrayList(); Iterator it = getChildIterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof SchemaNode) { schemas.add(o); } } return schemas; } /** * Returns "database" as the type for this node. * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#getType() */ public String getType() { return "database"; } /* * (non-Javadoc) * * @see net.sourceforge.sqlexplorer.dbstructure.nodes.INode#getUniqueIdentifier() */ public String getUniqueIdentifier() { return getQualifiedName(); } /** * Checks if a node name should be filtered. * * @param name to check for filtering * @return true if the name should be filtered */ private boolean isExcludedByFilter(String name) { if (_filterExpressions == null || _filterExpressions.length == 0) { // no active filter return false; } for (int i = 0; i < _filterExpressions.length; i++) { String regex = _filterExpressions[i].trim(); regex = TextUtil.replaceChar(regex, '?', "."); regex = TextUtil.replaceChar(regex, '*', ".*"); if (regex.length() != 0 && name.matches(regex)) { // we have a match, exclude node.. return true; } } // no match found return false; } /** * Loads childnodes, filtered to a subset of schemas/databases depending on * whether a comma separated list of regular expression filters has been * set. */ public void loadChildren() { _childNames = new ArrayList(); String metaFilterExpression = _session.getUser().getAlias().getSchemaFilterExpression(); if (metaFilterExpression != null && metaFilterExpression.trim().length() != 0) { _filterExpressions = metaFilterExpression.split(","); } else { _filterExpressions = null; } try { SQLDatabaseMetaData metadata = _session.getMetaData(); if (_supportsCatalogs) { final String[] catalogs = metadata.getCatalogs(); if (catalogs == null || catalogs.length == 0) { if (_supportsSchemas) _supportsCatalogs = false; } else { _supportsSchemas = false; for (int i = 0; i < catalogs.length; ++i) { _childNames.add(catalogs[i]); if (!isExcludedByFilter(catalogs[i])) { addChildNode(new CatalogNode(this, catalogs[i], _session)); } } } } if (!_supportsCatalogs && _supportsSchemas) { final String[] schemas = metadata.getSchemas(); for (int i = 0; i < schemas.length; ++i) { _childNames.add(schemas[i]); if (!isExcludedByFilter(schemas[i])) { addChildNode(new SchemaNode(this, schemas[i], _session)); } } } if (!_supportsCatalogs && !_supportsSchemas) { addChildNode(new CatalogNode(this, Messages.getString("NoCatalog_2"), _session)); } // load extension nodes String databaseProductName = _databaseProductName.toLowerCase().trim(); IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint point = registry.getExtensionPoint("net.sourceforge.sqlexplorer", "node"); IExtension[] extensions = point.getExtensions(); for (int i = 0; i < extensions.length; i++) { IExtension e = extensions[i]; IConfigurationElement[] ces = e.getConfigurationElements(); for (int j = 0; j < ces.length; j++) { try { // include only nodes that are attachted to the root // node.. String parent = ces[j].getAttribute("parent-node"); if (!parent.equalsIgnoreCase("root")) { continue; } boolean isValidProduct = false; String[] validProducts = ces[j].getAttribute("database-product-name").split(","); // include only nodes valid for this database for (int k = 0; k < validProducts.length; k++) { String product = validProducts[k].toLowerCase().trim(); if (product.length() == 0) { continue; } if (product.equals("*")) { isValidProduct = true; break; } String regex = TextUtil.replaceChar(product, '*', ".*"); if (databaseProductName.matches(regex)) { isValidProduct = true; break; } } if (!isValidProduct) { continue; } String type = ces[j].getAttribute("table-type").trim(); AbstractNode childNode = (AbstractNode) ces[j].createExecutableExtension("class"); childNode.setParent(this); childNode.setSession(_session); childNode.setType(type); addChildNode(childNode); } catch (Throwable ex) { SQLExplorerPlugin.error("Could not create child node", ex); } } } } catch (Exception e) { SQLExplorerPlugin.error("Error loading children", e); } } /** * @return true if this database supports catalogs */ public boolean supportsCatalogs() { return _supportsCatalogs; } /** * @return true if this database supports schemas */ public boolean supportsSchemas() { return _supportsSchemas; } }