Writing a jConduit.
So you want to synchronize your PalmOS handheld
with your favourite application or database, but such a facility doesn't exist,
or you want to roll your own to control what goes onto your handheld and
when.
So you want to synchronize your PalmOS handheld
with your favourite application or database, but such a facility doesn't exist,
or you want to roll your own to control what goes onto your handheld and when.
You have some Java experience, but are new to the world of writing
conduits.This is the sort of thing the
jSyncManager was designed to handle, and writing synchronization plug-ins (known
as jConduits) can be quick and easy. This article will briefly describe what
you need to begin.(Note that this
article will describe the steps to take to create a basic jConduit for
synchronizing with an application or database at the record level, or via VFS.
If you want to synchronize by writing PRC, PDB, or PQA files to the handheld,
there is a special abstract jConduit class you can use to simplify this sort of
synchronization called
AbstractInstaller,
which will be covered in a future
article).First off, you'll need the
following to develop your jConduit: -
A Java Software Development Kit, version 1.4 or better
recommended, - The jSyncManager API (for this article, we're
assuming the v3.2 API).(You may also
want the jSyncManager
Core Application Set and the necessary transport APIs if you want to
test your jConduit -- this article will only deal with what you need to write
and compile your jConduit).Once you
have the parts you need, you'll want to ensure the jSyncManager API JAR file is
somewhere where your JDK is going to be able to find it at compile time. Your
jre/lib/ext directory is a good place, but if you don't have access to such a
directory, anywhere in your CLASSPATH is fine. Various IDEs may also support
importing the JAR for automatic compile-time
interrogation.Creating your
jConduit Class:The first thing
you'll want to do is to create a class in which to define your new jConduit.
There are some rules the jSyncManager expects you to follow in creating a
package name space for your jConduit to make it
load-able: - Your jConduit must be in
a package inside the org.jSyncManager.Conduit
package, - The
package name you choose must exactly match the name you choose for your jConduit
class.Thus, if you wish to call your
jConduit
MyConduit,
you'd need to put it into the package
org.jSyncManager.Conduit.MyConduit.
Note that any supplementary classes you develop can be in whatever package you
like -- only the jConduit entry point must be in the
org.jSyncManager.Conduit
package.(The original rationale for
this was that it was hoped that one day Java would have the ability to query the
available packages/classes within a given package, allowing the jSyncManager to
dynamically discover all available jConduits on a given system. This facility
doesn't look like it's ever going to exist, so this requirement may change in a
future release).All jConduits are
derived from a common ancestor class called
AbstractConduit
(found in the
org.jSyncManager.API.Conduit
package). As such, your jConduit class must sub-class
AbstractConduit: package
org.jSyncManager.Conduit.MyConduit; import
org.jSyncManager.API.Conduit.AbstractConduit; public
class MyConduit extends AbstractConduit
{ ...Implementing
your Constructor:The
jSyncManager jConduit API only recognizes one constructor signature, and that's
the no parameter constructor. You may define other constructors, but they won't
be called when your jConduit is installed. Only the no parameter constructor
will be called.Implementing
the Basic Methods:If you check
the JavaDoc (or the source code) for the
AbstractConduit
class, there are a number of available methods which you can override and
extend. However, you are only
required
to implement three methods: -
getResourceBundleName()
-
constructConfigPanel()
- startSync(ConduitHandler,
DLPUserInfo)Implementing the
first method is easy. To encourage easily translatable jConduits, the jConduit
subsystem has some built-in resource handling. Data such as the name of your
jConduit, its description, and information on who wrote it can be contained
within a resource bundle you specify. This method simply returns its
fully-qualified name. Note that you can use any type of resource bundle
supported by Java, including
ResourceBundle,
ListResourceBundle,
or a
PropertyResourceBundle.
Due to the ease of maintenance, we generally use
PropertyResourceBundles
in the jSyncManager.(Note that you can
bypass the use of a resource bundle if you insist by re-implementing the
getConduitName()
and
getConduitDescription()
methods, but this is highly
discouraged).You can have whatever
resource keys you want within your resource bundle, however the following
resources
must
be present: # Property file
metadata Language=<name of the
language these resources are in, in that language (ie:
"English")> Translator=<name of
the person who did the
translation> Translator
E-Mail=<e-mail address of the person who did the
translation> # jConduit
Properties conduit.name=<name of
the jConduit (ie:
"MyConduit")> conduit.description=<description
of your jConduit>Note that if
you wish to access resources within your bundle, you can call the
getConduitResourceBundle() method inside your jConduit. The
AbstractConduit
class takes care of the loading and caching of your resource bundle the first
time it is needed, so there is no need to load it
yourself.The next method to be
implemented is the
constructConfigPanel()
method. This method returns a
javax.swing.JPanel
instance containing whatever GUI controls of widgets you want to present the
user with when they choose to configure your jConduit. If you don't need any
configuration (such as a path to a data file or directory, user login
information, etc.), it's perfectly safe to just return
null
here.The last method you need to
implement is the startSync(ConduitHandler,
DLPUserInfo) method. This method is the
entry point to the actual meat of where your synchronization logic is going to
reside, and provides you with the tool you need to open handheld database, read
and write records, resources, VFS files, and entire database, so routine
maintenance, query various handheld information and other synchronization tasks
-- the
ConduitHandler
class. Describing the
ConduitHandler
class is outside the scope of this article, but it has extensive JavaDoc
documentation to help you write your jConduit. Your jConduit is also passed a
reference to the handheld users information, so you can do whatever special
per-user validation or synchronization handling you may want to do (for example,
you may want to use the handheld user name to get the rows of a database table
specifically for that user in a local or networked
DBMS).A few things to note about the
startSync
method. First is that it throws the
NotConnectedException.
Your startSync
implementation generally shouldn't catch this exception internally, as it is
raised when the connection to the handheld has been lost -- and event that must
be registered by the jConduit synchronization engine which calls your jConduit.
If you must catch this exception to determine if the connection has been lost
mid-sync, please be sure to re-throw it so the synchronization engine knows the
connection has been lost, eg: catch
(NotConnectedException nce)
{ System.err.println("Oops -- the
connection was lost!"); throw
nce; } //
end-catchThat's it -- once you've
implemented these three methods, you have yourself a basic jConduit that can be
loaded and run by the
jSyncManager.Other jConduit
Methods:The
AbstractConduit
class also contains a number of other non-final methods which you can extend to
enhance your jConduit in different ways. For example, you can specify tasks to
be performed each time your jConduit is initialized. You can also specify the
priority of your jConduit (which is very useful in cases where you're writing a
suite of jConduits, and want them to run in a specific order). There is also a
method to let you know when the user has dismissed the dialog containing your
jConduits configuration panel, letting you know whether they selected "Ok" or
"Cancel". For information on these methods, consult the JavaDoc
for the AbstractConduit
class.A
Note on jConduit Preference
Storage:One of the nice tasks
that the jConduit API can relieve you of is the storage of persistent jConduit
state information. This can be user settings or other information you'd like to
track concerning the synchronization
process.When the jSyncManager is
exited normally, each jConduit instance is
serialized
to disk inside the users java.home
directory (in a directory called
.jsyncmanager).
Each instance variable you define (and don't flag as
transient)
will be saved to disk at exit time. Each jConduit is
deserialized
at load time, will all previous state information
intact.This system has a few results
you should be aware of: - Your
jConduits constructor is only called when your jConduit is initially installed.
As it's serialized and deserialized thereafter, the constructor won't be called
again. If you need to do any load-time jConduit initialization, do it in the
initialize()
method. - You can make variables for
which it doesn't make any sense to serialize all of the data so that they don't
get stored at serialization time by specifying the Java
transient
modifier. If you need to use this because you're referencing a type which isn't
serializable, you can initialize the variable in the
initialize()
method as above.Further
Reading: - jConduit Development By Example - DRAFT
- The jSyncManager
JavaDoc - Sample jConduit Sources
Posted: Friday - April 01, 2005 at 10:45 PM
|
Quick Links
Statistics
Total entries in this blog:
Total entries in this category:
Published On: Aug 30, 2007 08:14 PM
|