Issue 134308: Provide API that allows other modules to register actions on a database node diff --git a/db.mysql/src/org/netbeans/modules/db/mysql/impl/MySQLActionProvider.java b/db.mysql/src/org/netbeans/modules/db/mysql/impl/MySQLActionProvider.java --- a/db.mysql/src/org/netbeans/modules/db/mysql/impl/MySQLActionProvider.java +++ b/db.mysql/src/org/netbeans/modules/db/mysql/impl/MySQLActionProvider.java @@ -43,7 +43,7 @@ import java.util.ArrayList; import java.util.List; import javax.swing.Action; -import org.netbeans.modules.db.api.explorer.ActionProvider; +import org.netbeans.modules.db.api.explorer.RootNodeActionProvider; import org.openide.util.actions.SystemAction; /** @@ -52,7 +52,7 @@ * * @author David Van Couvering */ -public class MySQLActionProvider implements ActionProvider { +public class MySQLActionProvider implements RootNodeActionProvider { private static final MySQLActionProvider DEFAULT = new MySQLActionProvider(); private final ArrayList actions = new ArrayList(); diff --git a/db.mysql/src/org/netbeans/modules/db/mysql/layer.xml b/db.mysql/src/org/netbeans/modules/db/mysql/layer.xml --- a/db.mysql/src/org/netbeans/modules/db/mysql/layer.xml +++ b/db.mysql/src/org/netbeans/modules/db/mysql/layer.xml @@ -49,10 +49,10 @@ - + - + diff --git a/db/apichanges.xml b/db/apichanges.xml --- a/db/apichanges.xml +++ b/db/apichanges.xml @@ -105,6 +105,20 @@ + + + Add ability to register actions with database connection nodes + + + + + + With this change modules can register actions with database connection nodes. + The action is registered for all nodes, but can be selectively enabled/disabled + as needed. + + + Add ability to get the underlying JDBC Driver instance for a JDBCDriver diff --git a/db/arch.xml b/db/arch.xml --- a/db/arch.xml +++ b/db/arch.xml @@ -367,6 +367,52 @@ SQLIdentifiers.Quoter class is provided for this.

+ +

+ This feature allows modules to provide useful features to users by registering + one or more actions with a Database Explorer connection node. +

+

+ The module registers an implementation of + ConnectionActionProvider in its layer file under the folder + Databases/ConnectionActionProvider. The provider's + + getActions() + method is invoked by the Database Explorer whenever a connection node needs to know what actions + to display. This method is passed in the + DatabaseConnection + for the current selected connection, and you can choose which actions, if any, + you want to make available for this connection. +

+

+ Here is an example registration of an ActionProvider: +

+
+    <folder name="Databases">
+        <folder name="ConnectionActionProvider">
+            <file name="MyConnectionActionProvider.instance">
+                <attr name="instanceCreate" methodvalue="org.netbeans.testdriver.MyConnectionActionProvider.getDefault"/>
+                <attr name="instanceOf" stringvalue="org.netbeans.api.db.explorer.ConnectionActionProvider"/>
+            </file>
+        </folder>
+    </folder>
+    
+

+ The action can obtain the current + DatabaseConnection + by implementing + CookieAction and + specifying DatbaseConnection.class in the + cookieClasses() method. + Then in the + enable() + and + performAction() + methods of the action, you can call + Node.getCookie(DatabaseConnection.class) + to get the DatabaseConnection. +

+
diff --git a/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java b/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java --- a/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java +++ b/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java @@ -44,6 +44,7 @@ import java.sql.Connection; import org.netbeans.modules.db.explorer.ConnectionList; import org.netbeans.modules.db.explorer.DatabaseConnectionAccessor; +import org.openide.nodes.Node; /** * Encapsulates a database connection. Each DatabaseConnection instance @@ -64,7 +65,7 @@ * * @see ConnectionManager */ -public final class DatabaseConnection { +public final class DatabaseConnection implements Node.Cookie { private org.netbeans.modules.db.explorer.DatabaseConnection delegate; diff --git a/db/src/org/netbeans/modules/db/explorer/DbActionLoader.java b/db/src/org/netbeans/modules/db/explorer/RootNodeActionLoader.java rename from db/src/org/netbeans/modules/db/explorer/DbActionLoader.java rename to db/src/org/netbeans/modules/db/explorer/RootNodeActionLoader.java --- a/db/src/org/netbeans/modules/db/explorer/DbActionLoader.java +++ b/db/src/org/netbeans/modules/db/explorer/RootNodeActionLoader.java @@ -54,7 +54,7 @@ * * @author David Van Couvering */ -public interface DbActionLoader { +public interface RootNodeActionLoader { /** * Get all the registered actions */ diff --git a/db/src/org/netbeans/modules/db/explorer/DbActionLoaderSupport.java b/db/src/org/netbeans/modules/db/explorer/RootNodeActionLoaderSupport.java rename from db/src/org/netbeans/modules/db/explorer/DbActionLoaderSupport.java rename to db/src/org/netbeans/modules/db/explorer/RootNodeActionLoaderSupport.java --- a/db/src/org/netbeans/modules/db/explorer/DbActionLoaderSupport.java +++ b/db/src/org/netbeans/modules/db/explorer/RootNodeActionLoaderSupport.java @@ -49,20 +49,20 @@ import org.openide.util.Lookup; /** - * Supporting methods to work with the registered implementation of ActionLoader + * Supporting methods to work with the registered implementation of RootNodeActionLoader * * @author David Van Couvering */ -public class DbActionLoaderSupport { +public class RootNodeActionLoaderSupport { - private DbActionLoaderSupport() { + private RootNodeActionLoaderSupport() { } public static List getAllActions() { List actions = new ArrayList(); - Collection loaders = Lookup.getDefault().lookupAll(DbActionLoader.class); + Collection loaders = Lookup.getDefault().lookupAll(RootNodeActionLoader.class); for (Iterator i = loaders.iterator(); i.hasNext();) { - actions.addAll(((DbActionLoader)i.next()).getAllActions()); + actions.addAll(((RootNodeActionLoader)i.next()).getAllActions()); } return actions; diff --git a/db/src/org/netbeans/modules/db/explorer/infos/ConnectionNodeInfo.java b/db/src/org/netbeans/modules/db/explorer/infos/ConnectionNodeInfo.java --- a/db/src/org/netbeans/modules/db/explorer/infos/ConnectionNodeInfo.java +++ b/db/src/org/netbeans/modules/db/explorer/infos/ConnectionNodeInfo.java @@ -48,9 +48,15 @@ import java.sql.DatabaseMetaData; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.Action; +import org.netbeans.api.db.explorer.ConnectionActionProvider; import org.netbeans.lib.ddl.DBConnection; import org.netbeans.lib.ddl.DatabaseProductNotFoundException; import org.netbeans.lib.ddl.impl.DriverSpecification; @@ -68,6 +74,7 @@ //import org.netbeans.modules.db.explorer.PointbasePlus; import org.openide.util.Exceptions; //import org.openide.nodes.Node; +import org.openide.util.lookup.Lookups; //import org.netbeans.modules.db.explorer.nodes.ConnectionNode; @@ -318,8 +325,39 @@ } - - + + @Override + public Vector getActions() { + Vector actions = super.getActions(); + List registeredActions = getRegisteredActions(getDatabaseConnection()); + + if (registeredActions == null || registeredActions.size() == 0) { + return actions; + } + + // Add a delimiter + actions.add(null); + + actions.addAll(registeredActions); + + return actions; + } + + private static final String ACTION_PROVIDER_PATH = "Databases/ConnectionActionProvider"; + private List getRegisteredActions(DatabaseConnection dbconn) { + List actions = new ArrayList(); + Collection providers = (Collection) + Lookups.forPath(ACTION_PROVIDER_PATH).lookupAll(ConnectionActionProvider.class); + + for (ConnectionActionProvider provider : providers) { + List actionList = provider.getActions(dbconn.getDatabaseConnection()); + if (actionList != null) { + actions.addAll(actionList); + } + } + + return actions; + } private void connect(String dbsys) throws DatabaseException { String drvurl = getDriver(); diff --git a/db/src/org/netbeans/modules/db/explorer/infos/RootNodeInfo.java b/db/src/org/netbeans/modules/db/explorer/infos/RootNodeInfo.java --- a/db/src/org/netbeans/modules/db/explorer/infos/RootNodeInfo.java +++ b/db/src/org/netbeans/modules/db/explorer/infos/RootNodeInfo.java @@ -59,7 +59,7 @@ import org.netbeans.modules.db.explorer.DatabaseConnection; import org.netbeans.modules.db.explorer.ConnectionList; import org.netbeans.modules.db.explorer.DatabaseOption; -import org.netbeans.modules.db.explorer.DbActionLoaderSupport; +import org.netbeans.modules.db.explorer.RootNodeActionLoaderSupport; import org.netbeans.modules.db.explorer.DbNodeLoader; import org.netbeans.modules.db.explorer.DbNodeLoaderSupport; import org.netbeans.modules.db.explorer.nodes.*; @@ -197,7 +197,7 @@ public Vector getActions() { Vector actions = super.getActions(); - List loadedActions = DbActionLoaderSupport.getAllActions(); + List loadedActions = RootNodeActionLoaderSupport.getAllActions(); Vector allActions = new Vector(); diff --git a/db/src/org/netbeans/modules/db/explorer/nodes/ConnectionNode.java b/db/src/org/netbeans/modules/db/explorer/nodes/ConnectionNode.java --- a/db/src/org/netbeans/modules/db/explorer/nodes/ConnectionNode.java +++ b/db/src/org/netbeans/modules/db/explorer/nodes/ConnectionNode.java @@ -44,11 +44,18 @@ import java.awt.datatransfer.Transferable; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import javax.swing.Action; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import org.netbeans.api.db.explorer.ConnectionActionProvider; import org.netbeans.modules.db.explorer.DatabaseConnection; import org.netbeans.api.db.explorer.DatabaseMetaDataTransfer; import org.netbeans.modules.db.explorer.ConnectionList; @@ -62,6 +69,7 @@ import org.openide.util.RequestProcessor; import org.openide.util.WeakListeners; import org.openide.util.datatransfer.ExTransferable; +import org.openide.util.lookup.Lookups; /** * Node representing open or closed connection to database. @@ -99,8 +107,16 @@ private void setPropSupport(boolean value) { createPropSupport = value; } - - + + @Override + @SuppressWarnings("unchecked") + public Node.Cookie getCookie(Class cls) { + if (cls == org.netbeans.api.db.explorer.DatabaseConnection.class) { + return (Node.Cookie)info.getDatabaseConnection().getDatabaseConnection(); + } else { + return super.getCookie(cls); + } + } private void update() { RequestProcessor.getDefault().post(new Runnable() { diff --git a/dbapi/src/META-INF/services/org.netbeans.modules.db.explorer.DbActionLoader b/dbapi/src/META-INF/services/org.netbeans.modules.db.explorer.DbActionLoader --- a/dbapi/src/META-INF/services/org.netbeans.modules.db.explorer.DbActionLoader +++ b/dbapi/src/META-INF/services/org.netbeans.modules.db.explorer.DbActionLoader @@ -1,1 +1,1 @@ -org.netbeans.modules.dbapi.DbActionLoaderImpl +org.netbeans.modules.dbapi.RootNodeActionLoaderImpl diff --git a/dbapi/src/org/netbeans/modules/db/api/explorer/ActionProvider.java b/dbapi/src/org/netbeans/modules/db/api/explorer/RootNodeActionProvider.java rename from dbapi/src/org/netbeans/modules/db/api/explorer/ActionProvider.java rename to dbapi/src/org/netbeans/modules/db/api/explorer/RootNodeActionProvider.java --- a/dbapi/src/org/netbeans/modules/db/api/explorer/ActionProvider.java +++ b/dbapi/src/org/netbeans/modules/db/api/explorer/RootNodeActionProvider.java @@ -52,7 +52,7 @@ *

* @author David Van Couvering */ -public interface ActionProvider { +public interface RootNodeActionProvider { /** * @return the list of actions provided */ diff --git a/dbapi/src/org/netbeans/modules/dbapi/DbActionLoaderImpl.java b/dbapi/src/org/netbeans/modules/dbapi/RootNodeActionLoaderImpl.java rename from dbapi/src/org/netbeans/modules/dbapi/DbActionLoaderImpl.java rename to dbapi/src/org/netbeans/modules/dbapi/RootNodeActionLoaderImpl.java --- a/dbapi/src/org/netbeans/modules/dbapi/DbActionLoaderImpl.java +++ b/dbapi/src/org/netbeans/modules/dbapi/RootNodeActionLoaderImpl.java @@ -46,8 +46,8 @@ import java.util.Iterator; import java.util.List; import javax.swing.Action; -import org.netbeans.modules.db.api.explorer.ActionProvider; -import org.netbeans.modules.db.explorer.DbActionLoader; +import org.netbeans.modules.db.api.explorer.RootNodeActionProvider; +import org.netbeans.modules.db.explorer.RootNodeActionLoader; import org.openide.util.lookup.Lookups; /** @@ -56,20 +56,20 @@ * * @author David Van Couvering */ -public class DbActionLoaderImpl implements DbActionLoader { +public class RootNodeActionLoaderImpl implements RootNodeActionLoader { /** * Not private because used in the tests. */ - static final String ACTION_PROVIDER_PATH = "Databases/ActionProviders"; // NOI18N + static final String ACTION_PROVIDER_PATH = "Databases/RootNodeActionProvider"; // NOI18N public List getAllActions() { List actions = new ArrayList(); Collection providers = Lookups.forPath(ACTION_PROVIDER_PATH). - lookupAll(ActionProvider.class); + lookupAll(RootNodeActionProvider.class); for (Iterator i = providers.iterator(); i.hasNext();) { - ActionProvider provider = (ActionProvider)i.next(); + RootNodeActionProvider provider = (RootNodeActionProvider)i.next(); List actionList = provider.getActions(); if (actionList != null) { actions.addAll(actionList);