--- a/db/src/org/netbeans/api/db/explorer/node/Bundle.properties +++ a/db/src/org/netbeans/api/db/explorer/node/Bundle.properties @@ -144,6 +144,8 @@ KeySeqDescription=Keyseq ConnectionProperties=Connection properties ConnectionPropertiesDescription=Connection properties +SeparateSystemTables=Show system tables separately +SeparateSystemTablesDescription=Use special node for system tables # Booleans --- a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java +++ a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java @@ -164,6 +164,8 @@ */ private Properties connectionProperties = new Properties(); + private volatile boolean separateSystemTables = false; + /** * The API DatabaseConnection (delegates to this instance) */ @@ -1335,4 +1337,14 @@ public boolean isImportantCatalog(String database) { return importantCatalogs != null && importantCatalogs.contains(database); } + + public boolean isSeparateSystemTables() { + return separateSystemTables; + } + + public void setSeparateSystemTables(boolean separateSystemTables) { + boolean oldVal = this.separateSystemTables; + this.separateSystemTables = separateSystemTables; + propertySupport.firePropertyChange("separateSystemTables", oldVal, separateSystemTables); //NOI18N + } } --- a/db/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertor.java +++ a/db/src/org/netbeans/modules/db/explorer/DatabaseConnectionConvertor.java @@ -252,6 +252,7 @@ for (String importantDatabase : handler.importantCatalogs) { dbconn.addImportantCatalog(importantDatabase); } + dbconn.setSeparateSystemTables(handler.separateSystemTables); LOGGER.fine("Created DatabaseConnection[" + dbconn.toString() + "] from file: " + handler.connectionFileName); return dbconn; @@ -431,6 +432,9 @@ pw.println(" "); //NOI18N } } + if (instance.isSeparateSystemTables()) { + pw.println(" "); //NOI18N + } pw.println(""); //NOI18N } } @@ -450,6 +454,7 @@ private static final String ELEMENT_IMPORTANT_SCHEMA = "important-schema"; //NOI18N private static final String ELEMENT_IMPORTANT_CATALOG = "important-catalog"; //NOI18N private static final String ELEMENT_CONNECTION_PROPERTY = "connection-property"; // NOI18N + private static final String ELEMENT_SEPARATE_SYS_TABLES = "separate-system-tables"; //NOI18N private static final String ELEMENT_CONNECTION_PROPERTY_NAME = "name"; // NOI18N private static final String ELEMENT_CONNECTION_PROPERTY_VALUE = "value"; // NOI18N private static final String ATTR_PROPERTY_VALUE = "value"; // NOI18N @@ -467,6 +472,7 @@ String user; String displayName; Properties connectionProperties; + boolean separateSystemTables = false; List importantSchemas = new ArrayList(); List importantCatalogs = new ArrayList(); @@ -534,6 +540,8 @@ importantSchemas.add(value); } else if (ELEMENT_IMPORTANT_CATALOG.equals(qName)) { importantCatalogs.add(value); + } else if (ELEMENT_SEPARATE_SYS_TABLES.equals(qName)) { + separateSystemTables = Boolean.parseBoolean(value); } } --- a/db/src/org/netbeans/modules/db/explorer/node/ConnectionNode.java +++ a/db/src/org/netbeans/modules/db/explorer/node/ConnectionNode.java @@ -73,6 +73,7 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; +import org.openide.util.WeakListeners; import org.openide.util.actions.SystemAction; import org.openide.util.datatransfer.ExTransferable; @@ -86,6 +87,8 @@ private static final String DISCONNECTEDICONBASE = "org/netbeans/modules/db/resources/connectionDisconnected.gif"; // NOI18N private static final String CONNECTIONPROPERTIES = "ConnectionProperties"; //NOI18N private static final String CONNECTIONPROPERTIESDESC = "ConnectionPropertiesDescription"; //NOI18N + private static final String SEPARATESYSTEMTABLES = "SeparateSystemTables"; //NOI18N + private static final String SEPARATESYSTEMTABLESDESC = "SeparateSystemTablesDescription"; //NOI18N private static final String FOLDER = "Connection"; // NOI18N private static final RequestProcessor RP = new RequestProcessor(ConnectionNode.class.getName()); @@ -103,6 +106,7 @@ // the connection private final DatabaseConnection connection; + private PropertyChangeListener propertyChangeListener; /** * Constructor @@ -167,6 +171,10 @@ refreshNode = false; } else if (nps.getName().equals(CONNECTIONPROPERTIES)) { connection.setConnectionProperties((Properties) val); + } else if (nps.getName().equals(SEPARATESYSTEMTABLES) + && val instanceof Boolean) { + connection.setSeparateSystemTables((Boolean) val); + refreshNode = false; } super.setPropertyValue(nps, val); @@ -188,6 +196,7 @@ addProperty(USER, USERDESC, String.class, !connected, connection.getUser()); addProperty(REMEMBERPW, REMEMBERPWDESC, Boolean.class, !connected, connection.rememberPassword()); + addProperty(SEPARATESYSTEMTABLES, SEPARATESYSTEMTABLESDESC, Boolean.class, true, connection.isSeparateSystemTables()); addProperty(CONNECTIONPROPERTIES, CONNECTIONPROPERTIESDESC, Properties.class, !connected, connection.getConnectionProperties()); Property ps = getSheet().get(Sheet.PROPERTIES).get(CONNECTIONPROPERTIES); ps.setValue("canEditAsText", Boolean.FALSE); //NOI18N --- a/db/src/org/netbeans/modules/db/explorer/node/TableListNode.java +++ a/db/src/org/netbeans/modules/db/explorer/node/TableListNode.java @@ -60,6 +60,12 @@ * @author Rob Englander */ public class TableListNode extends BaseNode implements SchemaNameProvider { + + public enum Type { + + SYSTEM, STANDARD, ALL + } + private static final String NAME = "Tables"; // NOI18N private static final String SYSTEM_NAME = "SystemTables"; // NOI18N private static final String ICONBASE = "org/netbeans/modules/db/resources/folder.gif"; // NOI18N @@ -68,7 +74,7 @@ private MetadataElementHandle schemaHandle; private final DatabaseConnection connection; - private final boolean system; + private final Type type; /** * Create an instance of TableListNode. @@ -76,16 +82,16 @@ * @param dataLookup the lookup to use when creating node providers * @return the TableListNode instance */ - public static TableListNode create(NodeDataLookup dataLookup, NodeProvider provider, boolean system) { - TableListNode node = new TableListNode(dataLookup, provider, system); + public static TableListNode create(NodeDataLookup dataLookup, NodeProvider provider, Type type) { + TableListNode node = new TableListNode(dataLookup, provider, type); node.setup(); return node; } - private TableListNode(NodeDataLookup lookup, NodeProvider provider, boolean system) { - super(new ChildNodeFactory(lookup), lookup, system ? SYSTEM_FOLDER : FOLDER, provider); + private TableListNode(NodeDataLookup lookup, NodeProvider provider, Type type) { + super(new ChildNodeFactory(lookup), lookup, Type.SYSTEM.equals(type) ? SYSTEM_FOLDER : FOLDER, provider); this.connection = getLookup().lookup(DatabaseConnection.class); - this.system = system; + this.type = type; } @SuppressWarnings("unchecked") @@ -95,20 +101,22 @@ @Override public String getName() { - if(system) { - return NAME; - } else { - return SYSTEM_NAME; - } + switch (type) { + case SYSTEM: + return SYSTEM_NAME; + default: + return NAME; + } } @Override public String getDisplayName() { - if(system) { - return NbBundle.getMessage (TableListNode.class, "SystemTableListNode_DISPLAYNAME"); // NOI18N - } else { - return NbBundle.getMessage (TableListNode.class, "TableListNode_DISPLAYNAME"); // NOI18N - } + switch (type) { + case SYSTEM: + return NbBundle.getMessage(TableListNode.class, "SystemTableListNode_DISPLAYNAME"); // NOI18N + default: + return NbBundle.getMessage(TableListNode.class, "TableListNode_DISPLAYNAME"); // NOI18N + } } @Override @@ -118,11 +126,12 @@ @Override public String getShortDescription() { - if(system) { - return NbBundle.getMessage (TableListNode.class, "ND_SystemTableList"); //NOI18N - } else { - return NbBundle.getMessage (TableListNode.class, "ND_TableList"); //NOI18N - } + switch (type) { + case SYSTEM: + return NbBundle.getMessage(TableListNode.class, "ND_SystemTableList"); //NOI18N + default: + return NbBundle.getMessage(TableListNode.class, "ND_TableList"); //NOI18N + } } @Override @@ -182,4 +191,8 @@ return array[0]; } + + public Type getType() { + return type; + } } --- a/db/src/org/netbeans/modules/db/explorer/node/TableListNodeProvider.java +++ a/db/src/org/netbeans/modules/db/explorer/node/TableListNodeProvider.java @@ -42,55 +42,114 @@ package org.netbeans.modules.db.explorer.node; -import org.netbeans.api.db.explorer.node.BaseNode; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import org.netbeans.api.db.explorer.node.NodeProvider; import org.netbeans.api.db.explorer.node.NodeProviderFactory; +import org.netbeans.modules.db.explorer.DatabaseConnection; +import org.netbeans.modules.db.explorer.node.TableListNode.Type; +import org.netbeans.modules.db.metadata.model.api.MetadataElementHandle; +import org.netbeans.modules.db.metadata.model.api.Schema; +import org.openide.nodes.Node; import org.openide.util.Lookup; +import org.openide.util.WeakListeners; /** * * @author Rob Englander */ -public class TableListNodeProvider extends ConnectedNodeProvider { +public class TableListNodeProvider extends NodeProvider { + private final DatabaseConnection connection; + private PropertyChangeListener propertyChangeListener; + private boolean setup = false; + // lazy initialization holder class idiom for static fields is used // for retrieving the factory public static NodeProviderFactory getFactory() { return FactoryHolder.FACTORY; } + @Override + protected void initialize() { + if (connection.getConnector().isDisconnected()) { + removeAllNodes(); + setup = false; + } else { + if (!setup) { + setNodesForCurrentSettings(); + setup = true; + } + } + if (propertyChangeListener == null) { + propertyChangeListener = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals("separateSystemTables")) { //NOI18N + setNodesForCurrentSettings(); + } + } + }; + connection.addPropertyChangeListener(WeakListeners.propertyChange( + propertyChangeListener, connection)); + } + } + + private void setNodesForCurrentSettings() { + List newList = new ArrayList<>(); + if (connection.isSeparateSystemTables()) { + newList.add(TableListNode.create(createLookup(), this, Type.STANDARD)); + newList.add(TableListNode.create(createLookup(), this, Type.SYSTEM)); + } else { + newList.add(TableListNode.create(createLookup(), this, Type.ALL)); + } + setNodes(newList); + } + + /** + * Create a lookup for TableListNode. Each TableListNode needs a unique + * lookup, because it will be used as key for the node. + */ + private NodeDataLookup createLookup() { + NodeDataLookup lookup = new NodeDataLookup(); + lookup.add(connection); + + MetadataElementHandle schemaHandle = getLookup().lookup(MetadataElementHandle.class); + if (schemaHandle != null) { + lookup.add(schemaHandle); + } + return lookup; + } + private static class FactoryHolder { static final NodeProviderFactory FACTORY = new NodeProviderFactory() { + @Override public TableListNodeProvider createInstance(Lookup lookup) { - TableListNodeProvider provider = new TableListNodeProvider(lookup, false); + TableListNodeProvider provider = new TableListNodeProvider(lookup); return provider; } }; } - // lazy initialization holder class idiom for static fields is used - // for retrieving the factory - public static NodeProviderFactory getSystemFactory() { - return SystamFactoryHolder.FACTORY; + private TableListNodeProvider(Lookup lookup) { + super(lookup, new TableListNodeComparator()); + connection = getLookup().lookup(DatabaseConnection.class); } - private static class SystamFactoryHolder { - static final NodeProviderFactory FACTORY = new NodeProviderFactory() { - public TableListNodeProvider createInstance(Lookup lookup) { - TableListNodeProvider provider = new TableListNodeProvider(lookup, true); - return provider; + private static class TableListNodeComparator implements Comparator { + + @Override + public int compare(Node o1, Node o2) { + if (o1 instanceof TableListNode && o2 instanceof TableListNode) { + return (((TableListNode) o1).getType().equals(Type.SYSTEM)) + ? 1 : -1; + } else { + return o1.getDisplayName().compareToIgnoreCase(o2.getDisplayName()); } - }; - } - - private final boolean system; - - private TableListNodeProvider(Lookup lookup, boolean system) { - super(lookup); - this.system = system; - } - - @Override - protected BaseNode createNode(NodeDataLookup lookup) { - return TableListNode.create(lookup, this, system); + } } } --- a/db/src/org/netbeans/modules/db/explorer/node/TableNodeProvider.java +++ a/db/src/org/netbeans/modules/db/explorer/node/TableNodeProvider.java @@ -126,8 +126,8 @@ if (schema != null) { Collection tables = schema.getTables(); for (Table table : tables) { - if( ((! system) && table.isSystem()) || - (system && (! table.isSystem()))) { + if (connection.isSeparateSystemTables() && ((!system) && table.isSystem()) + || (system && (!table.isSystem()))) { continue; } MetadataElementHandle
handle = MetadataElementHandle.create(table); --- a/db/src/org/netbeans/modules/db/resources/mf-layer.xml +++ a/db/src/org/netbeans/modules/db/resources/mf-layer.xml @@ -189,11 +189,6 @@ - - - - -