How To Sync Satellite Forms Data to a Linux Server With jSyncManager
Previous Topic  Next Topic 

Problem:        How To Sync Satellite Forms Data to a Linux Server With jSyncManager


Solution:        An open source Java based server sync solution called jSyncManager (http://www.jsyncmanager.org) is available for Linux and other Java-capable environments.  Using the SatelliteForms contrib library written by Michael Schwarz of Technodane Software & Systems, this solution can be used to sync Satellite Forms data on Palm devices.  This article by Michael Schwarz describes this solution.


Using the SatelliteForms contrib library


Michael Schwarz

TechnoDane Software & Systems, LLC

http://www.technodane.com


1. Introduction


I wrote a Java library to support reading and writing SatelliteForms data using an open source Java-based Palm sync server called jSyncManager. jSyncManager is a full platform for syncing PalmOS devices. It supports serial, USB, and network syncing. It has a single user GUI mode and a multi-user server mode. This document doesn’t attempt to explain jSyncManager. Read other documentation and support information in the jSyncManager project for that. I will say that the way I set things up was to unpack the jSyncManager source code and I just added my conduit code to it. A conduit has to be in the org.jSyncManager.Conduit package and has to extend AbstractConduit. One thing that threw me at first was that you have to use javax.swing even if you are running in "server" mode only because AbstractConduit requires you to write a method called "constructConfigPanel" (to support the GUI mode) that returns a JPanel. Mine just returns a null and it works both for the GUI and Server mode.


This library was written to support a specific client. We built a field force automation application for PalmOS using SatelliteForms 6.1.1 and we had over 100 users using network sync through jSyncManager using this library.


The library has been released under the LGPL and included in the "contrib" folder of the jSyncManager project. It was written by Michael A. Schwarz and is "owned" by his company, TechnoDane Software & Systems, LLC.


We are happy to provide assitance in using the library. Contact Michael at mschwarz at technodane.com. Answering specific questions we’re happy to do for free. We also offer design and development services at competitive rates. We can also offer fixed bids.


2. Getting Started


Every class in the library has javadoc comments. The two most important classes for most users are SFTable and SFColumn. The library is found in the "contrib" directory of the jSyncManager source tree. As of this writing, the library can only be obtained via CVS.


The first thing you need to know is how SatelliteForms data tables end up being named. You will need an official creator ID for your application. The data tables end up with the name Eccccvvvv_SFTableName, where "cccc" is the four character creator ID that you register with Palmsoft. "vvvv" is a table version number (which IIRC is set in SatelliteForms to allow you to differentiate between versions of your tables. I never took advantage of this feature, we always upgraded everyone at the same time).


Execution of your conduit starts at the startSync method. It is called with an instance of ConduitHandler, which is the class through which you drive the sync session. For example, we call the getUserInfo method on the ConduitHandler object to obtain the sync name of the handheld being synced. This was how we identified the user. Be aware that when working in server mode, several invocations of your conduit may be running simultaneously. We chose to create an inner class called "Session" to hold separate data structures for each active user. See jSyncManager project code and documentation for more details on concurrency issues.


Use the openDatabase method on the ConduitHandler to open the table you want to sync. This returns a handle you use for subsequent operations. Now we get to the meat of using the SatelliteForms library.


3. The SFTable class


PalmOS databases have a "App Block," which is a "one per database" structure. SatelliteForms uses this to store the structure of the data that is in the actual records of the database (in a traditional PalmOS application, records a just blocks of bytes that are usually mapped into a C struct). In an SF application, this AppBlock describes the names, types, and sizes of columns.


This is where our library starts to help you. You do not need to parse this structure, or encode and decode records yourself. Use the ConduitHandler getApplicationBlock method to obtain this AppBlock record. You then pass the resulting structure to the constructor for our SFTable class. It might look like this:


byte mode = DLPDatabase.READ_MODE;

mode |= DLPDatabase.WRITE_MODE;

mode |= DLPDatabase.SHOW_SECRET;

try {

               dbHandle = conduitHandler.openDatabase("EAIac0000_CUSTOMERS", mode);

} catch (Exception e) {

               // Intercept exception for tracing, then "re-throw" for

               // normal error handling.


               e.printStackTrace(System.out);

               DBUtility.logEvent(s.db, s.syncID, "ABOVE THROWN for DB [" + databases[x] + "]");

               throw e;

}


int count = conduitHandler.getOpenDatabaseInfo(dbHandle);

conduitHandler.postToLog("Database claims " + count + " records.");


DLPBlock appBlock = conduitHandler.getApplicationBlock(dbHandle);


SFTable sft = new SFTable(appBlock);



Now that you have the SFTable instance, you can use it to get and set data from rows of that table. There are a couple of common ways to examine records from the handheld. One is to interate over all of them. The other is to look only at those marked "dirty," which means they were either created or modified on the handheld since the last sync.


If the table is always very small, interating all of them may make sense. But it is usually much more efficient to examine only the dirty records. Here’s how you do that:


try {

               DLPRecord dlpRec = cHdlr.readNextModifiedRecord(dbHandle);

               cols = sft.getColumns(dlpRec);

               SFColumn custname = (SFColumn) cols.get("CUSTNAME");

               SFColumn custaddr = (SFColumn) cols.get("CUSTADDR");

               SFColumn custcity = (SFColumn) cols.get("CUSTCITY");

               SFColumn custstate = (SFColumn) cols.get("CUSTSTATE");

               SFColumn custzip = (SFColumn) cols.get("CUSTZIP");

               cHdlr.deleteRecord(dbHandle, (byte) 0, dlpRec.getRecordID());

} catch (NotConnectedException nce) {

               throw new OurConduitException(nce);

}



Note that everything is cast to SFColumn. This is the abstract base class of all the SatelliteForms datatypes. At this level, everything is a String. You call the SFColumn methods getValue or setValue to read and write the data.


Details to keep in mind





4. Conclusion


This is a fairly light treatment of the jSyncManager SatelliteForms library. We hope to improve the documentation with your help. However, be aware that we do have Javadoc comments on our source code which we always try to improve. And the code itself is, of course, the most accurate documentation you could want. Contact us with your comments and questions. We would love to see other people get use out of this library.



Keywords:      jSyncManager, Java, Linux, Unix, open source, Technodane, Michael Schwarz


KB ID: 10085 

Updated: 2008-05-16


Satellite Forms KnowledgeBase Online

Satellite Forms Website Home