The DTP Driver Framework
Hi all...
In this article, we're going to cover an introduction to the DTP Driver Framework. What are Driver Templates/Driver Definitions? What do we do with them? Where does the UI fit in? Where does the properties provider fit in? Can I make a Driver Template into a hat? Where does the Database Definition fit in?
All of these questions and more will be answered by the end of the article, I hope.
So let's start with an easy one. What is a Driver Template? A Driver Template is a named collection of properties needed to define a usable Driver Definition.
A Driver Definition is a real instance of a Driver Template, with specific paths to driver jars or particular information to help users of that driver to create a Connection Profile that uses it.
We'll cover Connection Profiles in another article, but note that Driver Templates and Driver Definitions are optional for Connection Profiles. We use them for JDBC Connection Profiles because they provide an easy way to manage drivers and driver jars without duplicating that information in each Connection Profile instance.
Basically we have ([] = optional):
[Driver Template -> Driver Definition] -> Connection Profile
Each Driver Template can fall into one parent category, but categories can be split up in many ways. For example, we have a Database category, and then break that down by Vendor (IBM, Sybase, etc.) and Version (DB2 8.1, ASE 15, etc.). These categories provide groupings for Templates so we can refer to a parent category of Templates in particular controls used for Connection Profile creation/editing - like the DriverListCombo. You can give the DriverListCombo a category ID (like the one for Derby driver templates for example) and it will grab all of the Driver Definitions that use Driver Templates that fall under that category or any of its child categories.
(Brief sidebar... In Europa and before, we used to display Driver Definitions on the Driver Definitions preference page in a tree that followed this scheme... Databases -> Vendor -> Version -> Driver Definition, but now in Ganymede we arrange this differently so it's easier to sort by vendor or version or category to get at what you're looking for.)
Think of a Driver Template as a basic set of properties needed for a driver. Driver Templates require a unique ID, a name, and a parent category. Though jar lists are required for managing JDBC drivers, they're not mandatory for all Driver Templates, so you can specify if an empty jar list is ok. You can also provide a default name for Driver Definitions that use the Template as well as a class that can programmatically provide values for properties when Driver Definitions are created.
In addition, you can provide a list of other properties for the Driver Template. It's quite customizable. For JDBC templates, we require:
* Driver Class
* Vendor
* Version
* Database Name
* Connection URL
* User ID
* Password
As an example, the Derby Embedded JDBC Driver template for version 10.0 of Derby has the following basic properties:
* id = org.eclipse.datatools.connectivity.db.derby.genericDriverTemplate
* name = %DERBY_EMBEDDED_DRIVER_TEMPLATE_NAME (which resolves to "Derby Embedded JDBC Driver")
* description = <blank> (but this may be used in the future in the Driver Definition UI as a tooltip)
* parentCategory = org.eclipse.datatools.connectivity.db.derby.10_0.driverCategory, which is a child category of org.eclipse.datatools.connectivity.db.derby.driverCategory, which is a child category of org.eclipse.datatools.connectivity.db.driverCategory (so you can see the hierarchy - all Database drivers fall under "org.eclipse.datatools.connectivity.db.driverCategory", and then Derby further defines it to a "Derby" category and then a category for "10.0" beneath that)
* jarList = derby.jar (multiple jars could be specified here, and this property can be further modified by the valuesProvider class)
* createDefault = false (indicates whether we should create a default Driver Definition for this template when a new workbench is created for the first time)
* emptyJarListIsOK = false (indicates that a jar list is required for this Derby 10.0 template)
* valuesProvider = org.eclipse.datatools.connectivity.apache.internal.derby.driver.DerbyDriverValuesProvider101 (this is a class that implements the IDriverValuesProvider interface and is used in the Derby case to see if one of two JDBC driver file plug-in wrappers exists in the workbench - if it does, it will create a Driver Definition by default, changing the jarList to have a valid path to the jar and setting createDefault to true)
* defaultDefinitionName = %DERBY_EMBEDDED_DRIVER_DEFAULT_INSTANCE_NAME (resolves to "Derby Embedded JDBC Driver 10.0" and is used if the valuesProvider finds the right plug-ins and creates a default Driver Definition)
Then when a Driver Definition is instantiated for that Driver Template, it uses the values from the Driver Template as defaults and allows the user to modify them. Think of this as a concrete instance of a template. Sort of like a Microsoft Word template used to create a Microsoft Word document. The template just suggests some defaults for the document, but the document is the actual file being modified.
So with our Derby example, we create an instance of the Derby Driver Template that takes those defaults and allows the user to modify the values to make the Driver Definition "valid". This means in effect that a) any jar files specified in the jar/zip files list are accessible and b) any required properties have values. We point to a concrete path for our derby.jar file, maybe modify the default JDBC url and user name for our basic installation, and we're on our way.
As we mentioned earlier, if the valuesProvider class finds an appropriate plug-in wrapper for the Derby driver, it will create the Driver Definition by default and the user won't have to modify it unless they need to tweak the defaults for their installation.
Once we have a Driver Definition defined for a given database type, we can then create a Connection Profile that uses the properties of the Driver Definition as defaults (jar list and driver class are shared between the Driver Definition and the Connection Profile), and we can specialize our Profile details further, perhaps adding some optional properties to the url, a unique port or database name/path, or providing a more specific user name/password combination.
Now... I mentioned in my introduction last week that you can do more with Driver Templates and Driver Definitions than just use them in database Connection Profiles.
What if you want to define some basic communication protocols for a particular Connection Profile to consume? For example, you might define an "e-mail" driver that doesn't have any jars, but defines the basic properties of an SMTP server vs. a POP3 server vs. some other e-mail server type. So you could have two or three Driver Definitions that get consumed by an e-mail Profile (nobody's written one yet, want to volunteer?) to access and display e-mail sitting on a server somewhere.
Or maybe you want to use DTP to help manage connections to application servers? There's a wide variety of those... JBoss or Tomcat or EAServer or any number of others... Why not come up with a common Connection Profile that consumes "application server" Driver Definitions to show... message queues or provide administration functionality to start/stop a server, or view the log for the server.
Perhaps you're playing with social networking sites and you want to come up with a common set of functionality across them... Would you be able to perhaps use OpenSocial with DTP to provide that functionality?
There are a ton of possibilities to explore.
Think of Driver Templates and Driver Definitions as helpers for Connection Profiles. They're not required, but they can provide a place to share common details among profiles so you don't have to duplicate it in a bunch of profiles. For example, what if you have a bunch of database Profiles that don't use the Driver Framework and you want to update your driver class/jar list for a new version of the JDBC driver? Depending on how you implemented it, your user might have to go into each and every Profile that references the old files/driver class and update them by hand. Or if you use the Driver Framework, you update it in one place and the very next time you connect, it gets picked up automatically by the Profile.
So what do you think? Can you think of places where it would be handy to use DTP's Connection Profile and Driver Frameworks to meet a need?
As always, holler if you have questions or think I'm making this stuff up as I go along. I value the input of the community. There's LOTS of room to explore to see where we can take the DTP frameworks and I'm happy to be along for the ride!
Next week we'll start talking about how to implement your own custom Driver Templates.
Until next time...
--Fitz
Learn about Cluster Edition at Techwave
August may seem far away, but for those of us developing content for Techwave, it is right around the corner. This year’s Techwave conference has a lot of cluster related content, so if you’ve been curious about ASE Cluster Edition I recommend making the trip to Vegas.
Naturally the content is subject to change - but as of now I see five breakout sessions covering Cluster Edition as well as full-week, in-depth education seminar. It appears the education seminar will also be offered as a pre-conference course. If you sign up for a pre-conference course you can take a different full length class during the week. One of the breakouts I’ll be doing will show you how to setup a cluster on a laptop using VMware….should be fun!
DTP Article Series Introduction
Hi all...
I am going to be writing about some of the cool things you can do with the Data Tools Project (DTP) and how you can set up your own connection profiles for a variety of purposes. My goal with this series of articles is to provide a baseline for more people to understand the DTP frameworks for connectivity so they may build on them or use them in any way they see that's useful.
DTP is more than databases. Anyone who's played with BIRT realizes that ODA, which is a part of DTP Connectivity, shows the potential for accessing a variety of data sources, from comma separated files and XML to the variety of databases we support today through the DTP Enablement project. Though SQL is cool, it's nice to have the ability to have a consistent interface to your data when you're working in Eclipse.
So I'm going to break this into a series of articles and try to post fairly regularly -- probably one a week or so -- to cover the various bits and pieces of the DTP Connectivity frameworks and how a developer could use these bits and pieces in their own tools.
We're going to cover Driver Templates and Driver Definitions first, which might seem a bit odd considering what I said just a couple of paragraphs ago about DTP being more than just databases. However, Sybase has used driver templates in a few ways beyond just for JDBC drivers. We used them to describe properties of a security specification that could then be expanded on by adopters and users for their own purposes. Templates can be anything you want them to be and we'll cover some possible uses of the driver framework in the first series of articles.
Once we've covered drivers, we'll start talking about catalog loaders. Unlike drivers, catalog loaders are definitely a database-specific thing at this point, leveraging the Database Definition and SQL Model from the DTP Model Base project to populate a rich EMF model with JDBC-related information about a particular database. This allows you to do a variety of cool things with the SQL model.
And lastly, but definitely not least, we'll then cover the connection profile framework. Here's another area, like the driver framework, where you're not limited to databases. A connection profile can connect to a JDBC database, a CSV file, an XML file, or whatever you'd like to browse. By integrating with the Platform's Common Navigator Framework, you can integrate with file systems or FTP providers, or application servers, or newsgroups if you want to make a newsgroup reader -- pretty much anything you can connect to and pull back information from, you can make a connection profile for.
So as you can see, there's a lot of functionality available in DTP. I'll do what I can to help write about the various aspects of DTP Connectivity that you may not have known about.
As always, if you have questions, post them in the comments, post them on the newsgroup, post them on the mailing list -- wherever it's convenient for you to do so. And we'll do our best to get them answered in a timely manner.
Thanks for your time! Next week we'll start talking about the Driver framework.
--Fitz
TechWave Registration is now open!
Join us Aug. 4 – 8 at the Mandalay Bay Resort & Casino in Las Vegas, NV... for the 10th Annual Sybase User Training and Solutions Conference.
(More...)
Enabling command-line applications for your Eclipse projects
Hi all...
Recently in DTP we came across an opportunity to provide admin-level support for some import/export type functionality within Connectivity. And it was discussed that this would be best done as a command-line application, since administrators may not have access to or wish to use the full blown Eclipse UI to handle this task.
So we started doing some digging and discovered that there's this very cool framework within the Eclipse platform to handle just this kind of thing. A bit of Googling turned up this presentation from EclipseCon 2006:
Though the Eclipse platform has changed a bit since Jeffrey wrote his article, it got me going the right direction. So I thought we'd update it for Eclipse 3.3.2.
Here's the steps we did to create this sample project...
1) Create a new plug-in project.
2) Make sure to un-check the "This plug-in will make contributions to the UI" checkbox.
3) Uncheck any available plug-in templates.
And voila, you have a new plug-in.

4) Go to the Extensions tab of the Plug-in/Manifest Editor. Add a new Extension. Select the "org.eclipse.core.runtime.applications" extension point. Click Finish when you're done.
You have a new "application" node beneath your org.eclipse.core.runtime.application extension.
5) Select the actual extension point node in the tree and note the ID of the application. This is important (I learned this the hard way). You want to provide something unique here that's not too long. It gets prefaced by the ID of your plug-in when you try to run it later.
It defaults to "idX". Call it whatever you want. In this case, we'll call it "CoolApp". The full ID is then my.cool.application.CoolApp when we go to run this later.
6) Go back to the "application" node, right-click and click New->Run. This adds the node that specifies the class you're going to run in command-line mode when you invoke your plug-in application.
7) Click the class* link to create the application class. Our application class will implement the org.eclipse.equinox.app.IApplication interface. Give it a name ("CoolApplication" in our case) and click Finish.
So you end up with the beginnings of your application class:
8) In our case, we're just testing out this functionality, so we don't have to get too fancy. In the Start method, you get an IApplicationContext object, which gives you a whole lot of information about the command line parms that were passed in.
So we're going to add some code to check out those command line parms and just write them out intelligbly.
public Object start(IApplicationContext context) throws Exception {
// get the arguments
Map args = context.getArguments();
if (args.isEmpty()) {
// if there were no arguments, simply write "hello cool world"
System.out.println("hello cool world...");
} else {
// otherwise iterate through the arguments and print them as
// "key = value" pairs after "hello cool world"
Iterator iter = args.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
String output = new String();
if (key instanceof String) {
output = output + (String) key + "=";
}
Object value = args.get(key);
if (value instanceof String) {
output = output + (String) value;
}
System.out.println("hello cool world, " + output);
}
}
// And now we can attempt to get some input and respond from stdio
BufferedReader stdin = new BufferedReader
(new InputStreamReader(System.in));
String message; // Creates a variable called message for input
System.out.print ("Enter the message : ");
System.out.flush(); // empties buffer, before text is input
message = stdin.readLine();
System.out.print("You ");
System.out.println("entered : " + message);
// make sure to return an OK message
return EXIT_OK;
}
So now we save our class, make sure everything compiles and builds.
9) Then we export it as a deployable plug-in.
Pick the directory where you want the jarred plug-in to be written to. In my case, I want it to be installed directly in my Eclipse plug-ins directory (the "plugins" directory is added after the directory you specify as the destination). If you put the exported plugin somewhere else, you'll have to copy it into your Eclipse/plugins directory manually. Click Finish and it will put the plug-in where you specified.
10) Now head out to a console window. Assuming you have your Java environment set up correctly, all you should have to do to run the application is go to your Eclipse directory and type:
eclipsec -nosplash -application my.cool.application.CoolApp
And that's all there is to it! I know we're going to look into using this sort of application in the future to provide some command-line import/export functionality when we get a chance.
Hope this helped you out. The Eclipse Platform has lots of cool bits that most of us User Interface people never see!
Until next time... Keep on programming!
--Fitz
iPhone... part two
A few posts ago I wrote about how the iPhone (or full browsers on mobile phones) does not mean the end of mobile banking. And in that post I mentioned that I had some other reasons why mobile banking is different.
During the interim we've been interviewing candidates for a number of roles within Sybase 365, and with that post fresh in my mind, I thought I would ask the candidates the question iPhone vs. Mobile Banking. So here's some of the answers I got...
(More...)
|