Thursday, August 28, 2008

Creating the SQLite Connection Profile UI bits

Hi there!

So now we're almost to our first functional version of a SQLite connection profile in DTP. We have a driver-wrapper plug-in, a driver definition, an overridden catalog loader, and a connection profile with its associated connection and connection factory classes. What's next? Why, adding the UI so you can create the profile, of course!

With versions of DTP prior to Ganymede, this was a more difficult, but not horrible task. In Ganymede, we've reduced the amount of work to adding three extension points and writing four key classes in a org.eclipse.datatools.enablement.sqlite.ui plug-in (basically just extending these classes a tad, so little real work involved):
  • A connection profile wizard extension that uses the org.eclipse.datatools.connectivity.connectionProfile extension and uses the newWizard node so we can define our wizard
  • A property page extension (org.eclipse.ui.propertyPages) to define a property page so we can edit our SQLite conneciton profile instances
  • A driver UI contributor extension (org.eclipse.datatools.connectivity.ui.driverUIContributor) to create a reusable UI component that gathers the information we need for our SQLite connections
  • A connection profile wizard class that extends the org.eclipse.datatools.connectivity.ui.wizards.ExtensibleNewConnectionProfileWizard class
  • A connection profile wizard page that extends org.eclipse.datatools.connectivity.ui.wizards.ExtensibleProfileDetailsWizardPage
  • A connection profile property page that extends org.eclipse.datatools.connectivity.ui.wizards.ExtensibleProfileDetailsPropertyPage
  • And a driver UI component that is used on the wizard and property pages that implements org.eclipse.datatools.connectivity.ui.wizards.IDriverUIContributor
It may look daunting, but really it boils down to a few extension points, a few extended classes, and an instance of poor man's inheritance (copying a class from another project).

So let's get started!

Implementing the Driver UI Contributor Class

We're going to start with something that may seem a little backwards, but will make sense in a few minutes (hopefully). We're going to start with the driver UI component. Why? Because it's used on the property page and the wizard page, and will make our lives easier.

To avoid starting from scratch, I simply took the Derby Embedded driver UI contributor from the Derby UI project (org.eclipse.datatools.connectivity.apache.derby.ui is the plug-in project and you're looking for the DerbyEmbeddedDriverUIContributor class in package org.eclipse.datatools.connectivity.apache.derby.internal.ui.connection.drivers). You'll also probably want to grab the Messages class and properties files from that package.

After that, I just changed the names to protect the innocent for this first version. I'll go through and do a cleanup pass later. (I'll upload a zip with all of the code so you can play with it yourself.)

All we're doing is creating a basic UI that will gather the necessary information for the JDBC URL. The Derby UI works just fine for SQLite (for now), so why change anything?

Defining the Driver UI Contributor extension

So now that we have our driver UI contributor class, we can let DTP know about it. To do that, we define a "org.eclipse.datatools.connectivity.ui.driverUIContributor" extension point and add a new driverUIContributor node beneath it.

You can see that this is pretty straightforward as far as properties go.
  • id = a unique ID for the driver UI contributor
  • class = the fully qualified name of our driver UI contributor class
  • driverTemplateID = the ID for the driver we're defining the UI for
Pretty easy. Next, we'll set up the wizard.

Creating the Wizard

So new let's take a look at the newWizard part of the connectionProfile extension.

As you can see, we have a number of properties we need to fill out.
  • id = the unique ID for this particular connection profile wizard
  • name = the text that shows up in the list of connection profiles
  • class = this is the class that extends org.eclipse.datatools.connectivity.ui.wizards.ExtensibleNewConnectionProfileWizard (we'll cover it in just a minute)
  • profile = this is the ID of our connection profile that we created in the last article
  • icon = this is the image for the wizard. you can copy this icon directly out of any of the other connection profile UI plug-ins from the DTP CVS repository
  • description = a general description of what the wizard does that is displayed as a tooltip
  • category = not used
So now that we have our extension, let's work on our wizard and wizard page classes.

As metioned earlier, these are simply going to be extending a couple of classes that already exist in org.eclipse.datatools.connectivity.ui.
  • A connection profile wizard class that extends the org.eclipse.datatools.connectivity.ui.wizards.ExtensibleNewConnectionProfileWizard class
  • A connection profile wizard page that extends org.eclipse.datatools.connectivity.ui.wizards.ExtensibleProfileDetailsWizardPage
These classes look pretty darn easy.

Our wizard class looks like this:
package org.eclipse.datatools.enablement.sqlite.ui.connection;

import org.eclipse.datatools.connectivity.ui.wizards.ExtensibleNewConnectionProfileWizard;

public class NewSQLITEConnectionProfileWizard extends
ExtensibleNewConnectionProfileWizard {
public NewSQLITEConnectionProfileWizard() {
new SQLITEProfileDetailsWizardPage(
"org.eclipse.datatools.enablement.sqlite.ui.connection.SQLITEProfileDetailsWizardPage")); //$NON-NLS-1$

And our wizard page looks like this:
package org.eclipse.datatools.enablement.sqlite.ui.connection;

import org.eclipse.datatools.connectivity.ui.wizards.ExtensibleProfileDetailsWizardPage;
import org.eclipse.datatools.enablement.sqlite.ISQLITEConnectionProfileConstants;

public class SQLITEProfileDetailsWizardPage extends
ExtensibleProfileDetailsWizardPage {

public SQLITEProfileDetailsWizardPage(String pageName) {
super(pageName, ISQLITEConnectionProfileConstants.SQLITE_CATEGORY_ID);

You'll notice the reference to ISQLITEConnectionProfileConstants.SQLITE_CATEGORY_ID. That's just a way to point to the category of driver templates we're interested in for this connection profile. In our case, it looks like this:
public static final String SQLITE_CATEGORY_ID = "org.eclipse.datatools.enablement.sqlite.driver.category"; //$NON-NLS-1$
So now all we have left to do is define our property page.

Defining a SQLite property page

There's no special mojo for defining a property page for a connection profile. It works the same as it does elsewhere in Eclipse. You define a property page extension (org.eclipse.ui.propertyPages) and provide it a property page class.

Once that is done, we can work on the filter to indicate what type of object this is a property page for.

The filter is on the property and we set that to org.eclipse.datatools.enablement.sqlite.connectionProfile, which is the ID for our SQLite connection profile type.

And lastly, we specify when we want our property page to be enabled. And as seen in the last few screens, we merely want our page to be enabled when we're on a connection profile object.

The property page class itself is as simple as the wizard page was earlier. The class extends org.eclipse.datatools.connectivity.ui.wizards.ExtensibleProfileDetailsPropertyPage.

package org.eclipse.datatools.enablement.sqlite.ui.connection;

import org.eclipse.datatools.connectivity.ui.wizards.ExtensibleProfileDetailsPropertyPage;
import org.eclipse.datatools.enablement.sqlite.ISQLITEConnectionProfileConstants;

public class SQLITEProfilePropertyPage extends
ExtensibleProfileDetailsPropertyPage {

public SQLITEProfilePropertyPage() {

And that's really all there is to it.

Now we can test to make sure our wizard and property pages work.

From the Data Source Explorer when you create a new connection profile, you'll see the list of available profile types.

Once you've created it and connected, you can drill in and see something like this:

And to test the property pages, you can right-click on your profile and select Properties.

So now we have the start of SQLite support in DTP!

In the next article, I'll explain some of the bits and pieces we can do to clean this up and make it easier for users. Things like automatically creating the driver definition if the driver plug-in wrapper happens to be in the Eclipse environment.

Hopefully this has helped somebody doing some DTP development.

If you'd like to see me focus on other parts of DTP dev, let me know and I'll see what I can pull together. I'd love for some community-inspired questions to pop up!

Until next time...

Reblog this post [with Zemanta]


Ray da Costa said...

Hi Ray da Costa, you information that would provide the source ... What is the link that could get?

aliyaa said...

The personal voicemail greeting script provides best platform to learn more about these services. This have lot of chances of voice over.