This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
This issue is for the enhancement to the DB Explorer API for modules to register themselves in the layer as server providers.
This change does not impact modules that import the DB Explorer API or which the DB Explorer API depends on. This is adds an additional layer registration that we support. We also create a new SPI called ServerProvider which extends the DatabaseRuntime SPI. This feature allows third party modules to register a server provider, which allows users to provide additional functionality beyond start and stop. In particular, it allows them to register the server as a node in the Database Explorer and provide actions for this node. It is through this mechanism, for example, that Java DB can appear as a node under the Database Explorer (Services->Databases), and how we will provide functionality to be able to do basic management of local MySQL and PostgreSQL servers. JavaDoc for the new SPI, a description of the new layer, and full diffs of the changes will be provided.
Javadoc for the new ServerProvider API: /** * Represents an instance of a database server that can be managed. * * <p>Implementations of this class should be put in the Databases/Servers folder * in the default filesystem.</p> * * <p>If the implementation is registered and the canRegister() method returns * true, the server is added as a node to the Databases folder</p> * * @author David Van Couvering */ public interface ServerProvider extends DatabaseRuntime { /** * Return true if this server can be registered. For example, * if it's not installed and/or not running, then the provider * may choose to return false. * * If it returns true, then a node for the server will be displayed * under Services->Databases * * @return true if a server is available, false otherwise */ boolean canRegister(); /** * @return a list of all actions this server supports */ List getActions(); /** * @return the display name for this provider */ String getDisplayName(); /** * @return a short description of this provider */ public String getShortDescription(); }
A provider registers an instance of ServerProvider under the filesystem under the Databases/Runtimes folder. Note that ServerProvider extends DatabaseRuntime, so the provider will also be used for the existing DatabaseRuntime functionality (in particular, automatically starting the server when a connection is established). Here is an example registration: <folder name="Databases"> <folder name="Runtimes"> <file name="DerbyServerProvider.instance"> <attr name="instanceCreate" methodvalue="org.netbeans.modules.derby.DerbyServerProvider.getDefault"/> <attr name="instanceOf" stringvalue="org.netbeans.spi.db.explorer.ServerProvider"/> </file> </folder> </folder>
The changes have been committed to my local repository. They were in two different commits - one for the code changes and one for the doc changes. I am attaching both diffs.
Created attachment 56392 [details] Source change diffs
Created attachment 56393 [details] Doc changes diffs
I would like some clarification on what to do with an addition to an API marked as stable. I am concerned that this automatically makes the new SPI stable, when I don't think it's at that place yet. I marked it as "development" in the architectural spec, but I'm not sure how this works and would appreciate your guidance.
Apologies for the diffs, I specified the revisions in the wrong order in hg diff, so additions are represented as deletions.
Created attachment 56394 [details] Source change diffs, fixed
Created attachment 56395 [details] Doc change diffs, fixed
The second set of diffs have additions and deletions represented correctly
I think one more clarification is in order. Not all providers will be able to start and stop the server. When this is the case, they should return "false" for canStart(). If the DatabaseRuntime detects that canStart() is false, it will not attempt to start the server when the user tries to open a connection.
David, one module cannot have APIs of different stability levels. You also should not lower the stability level of an existing API (once there is a contract that the API is stable and somebody relies on this there should be no surprises for them). So there are only 2 ways (AFAICT): one is to make the new API stable, the other is to put the new API into a separate module which would have a lower stability level. I do not see any specific problems with the proposed extension. I suggest you try to get review by several other developers and try to go for option 1 (stable API) because the other option would be very impractical (at least).
Hm, that's too bad. It gives me pause about making interfaces stable, as this affects an entire module. We're going to want to continue to expand db support, and if that means that any new interfaces we want to introduce have to be immediately stable, it seems a little risky... But you're right, putting this in another module is not really a viable option, so committing to Stable immediately is really the only choice I have.
Can this interface change while NetBeans 6.1 is still not generally available? For example, I may find I want to add some more methods to the ServerProvider interface. Is that permissible prior to GA, or will I need to create another new interface once I check in the original one? Please say yes I can change it before GA ... :)
Yes, before GA it can change. You should pass any change through a review, of course.
AB01: since it seems the proposed API is going to change, I suggest moving it to the dbapi module, which only exposes a friend API. AB02: the methods of the proposed ServerProvider interface seems to map the methods needed to create a node for the respective server provider (getActions(), getShortDescription(), getDisplayName()). Perhaps better for the interface to just return a Node. AB03: better for ServerProvider to avoid implementing DatabaseRuntime. That interface is meant for starting a server when connecting to a database. As such, it can be implemented by a server-providing module separately. For starting a stopping a server as a response to Start and Stop actions in the UI, I can think of two solutions: - separate the isRunning(), canStart(), start() and stop() methods from DatabaseRuntime into a ServerStartStop interface and have the server provider implement it. This allows the DB Explorer to start a server programmatically. - do nothing and just expect the server-providing module to provide Start and Stop actions on the server node. I like this approach more, since I don't know an use case (other than the one already covered by DatabaseRuntime) requiring the DB Explorer to start a server programmatically.
I talked to Andrei on the phone, and he explained to me how the dbapi module has an implementation dependency on db module, and thus can use internal packages. Then you can create new apis that are available to friends only. So I'm going to migrate this new SPI to the dbapi module. I also liked Andrei's suggestion that we keep it simple and just make it a node registration API, reducing the amount of inter-module dependencies. This change makes the API non-public and thus not up for API review. I will keep this issue open for a week to see if there are any further comments, and then will close it with WONTFIX.
'This change makes the API non-public and thus not up for API review." - this seems to imply to me that only public API needs review. This is not quite true, even less stable APIs may deserve a review: http://openide.netbeans.org/tutorial/api-design.html#category-friend
Agreed, but it's not the case here, when the only client of the new API (the Java DB module) is in the database area too, and other clients will probably be developed by the same team.
Made this a new API in friend dbapi instead.