com.ibm.mobileservices.isync.midp
Class MIDPISyncProvider

java.lang.Object
  |
  +--com.ibm.mobileservices.isync.midp.MIDPISyncProvider
All Implemented Interfaces:
ISyncConfigStore, ISyncDriver, ISyncProvider, ISyncService

public class MIDPISyncProvider
extends java.lang.Object
implements ISyncDriver, ISyncProvider, ISyncService, ISyncConfigStore

This is the MIDP implementation of ISyncDriver.

Getting Started

Replication (or synchronization) is performed with an ISyncConfigStore object, which contains all information about subscription sets defined in the DB2 Everyplace Sync Server, via MDAC (Mobile Device Administration Control).

Initially, there is no information or data at the client, a refresh must be performed to get a snapshot of the current data. Once refreshed, future deltas made to the source database, or changes made on the client can be replicated via a synchronize request. The distinction of when to refresh versus sync is handled by ISyncDriver, however the user can return to the refresh state at any point in time, for all or specified subscription sets using reset

This API can either refresh only the Config, or the Config plus Sync Server data. It is faster, generally, to synchronize both at the same time using the sync method.

To only synchronize information about which subscription this user is subscribed to, refresh only the ISyncConfigStore using the syncConfig method.

However, if the application belongs to a MDAC Group which contains subscription sets which are not of interest to this application, it can disable the uninteresting subscription sets.

See the example below, and disable.

FastRecordStore and Index Classes for Data Access

Two classes are provided for reading and writing data to the underlying RMS (Record Management System).

It is required that applications use these two classes and not RecordStore directly, or data will be corrupted.

Processing Row Data

At this time there is no micro-JDBC implementation provided, however schema information is provided via the TableMetaData class.

The application is responsible for reading rows from the Index, and then reading the columns from the row.

As mentioned in TableMetaData, a dirty byte starts each row. If the application deletes, updates or inserts a row, the dirty byte must be appropriately set in the row, in order to be properly replicated.

See ROW_CLEAN, ROW_INSERT, ROW_CHANGED, and ROW_DELETED.

After synchronization, the ISync API clears all marked rows in tables whoose changes per sent up to the sync server.

Setting The Packet Size

The maximum row size supported by the Motorola/Nextel network is around 1400 bytes. The maximum packet size is 2944 bytes to the client phone and 1472 is the maximum packet size from the phone to the servlet.

We recommend on this Nextel network use a PREF_PACKET_DOWN_MAX of 2800 for data transfers from the Sync Server to the client, to allow for various additional headers in the packet. Use a PREF_PACKET_UP_MAX of 1400 for data transfers from the client to the Sync Server.

If a row is changed on the client and is synchronized up to the syncserver, the row must fit in the upload packet of 1400 bytes.

Example Usage


        public class MyClass extends MIDlet 
         implements CommandListener, ISyncListener, Runnable
    { 

        
........ ISyncProvider provider = MIDPISyncProvider.getInstance(); String URI = "http://199.99.9.9:8080"; Hashtable ht = new Hashtable(); ht.put("isync.user", userName); ht.put("isync.password", password); String lang = getAppProperty("Db2eSyncLang"); if (lang != null && lang.equals("jp")) ht.put("isync.encoding", "UnicodeBig"); ISyncService service = provider.createSyncService(URI, ht); ISyncConfigStore config = service.getConfigStore(null); ISyncDriver isync = config.getSyncDriver(); // The following values would typically be passed into the // MIDLET via the JAD file using // javax.microedition.midlet.MIDlet.getAppProperty(key) // try {
// Motorola i85 has a max packet size of 2800 down, 1400 up isync.setPref(ISync.PREF_PACKET_UP_MAX, "1400"); isync.setPref(ISync.PREF_PACKET_DOWN_MAX, "2800");
} catch (ISyncException ise) { // Unknown PREFerenceID } isync.setSyncListener(this); ..... // User changes sync modes via GUI or other methods ISyncSubscriptionSet[] subscriptionSets = config.getSubscriptionSets(); for (int ss = 0; subscriptionSets != null && ss < subscriptionSets.length; ss++) {
ISyncSubscriptionSet subscriptionSet = subscriptionSets[ss]; if (not_Of_Interest_To_Us)
subscriptionSet.disable();
else
subscriptionSet.enable();
} ... // Code for when the user hits the Sync button // Syncs allowing user cancel must run in a thread. Thread syncThread = new Thread(this); syncThread.start(); // We sync in a separate thread if we want to give the // user the ability to cancel the sync. // A cancel while refreshing configuration will require // a future full configuration refresh. int syncStatus; run() {
syncStatus = config.syncConfig(); if (syncStatus != ISync.RTN_SUCCEEDED) return; syncStatus = config.sync(); if (syncStatus != ISync.RTN_SUCCEEDED) {
// loop through the subscription sets and check status int status = subscriptionSet.getStatus(); // do something, continue or not.
}
} // or isync.sync() to sync all subscriptions including config
} .... // After thread completes, commit any user modifications // to subscription info, e.g. reset, disable, enable, // to persistent storage. isync.close(); }

Listener Interface Example

For examples of the ISyncListener.eventIssued methods, see the demos provided with this release.

        
public int eventIssued(ISyncEvent syncEvent) {
int eventCode = syncEvent.getEventCode(); String eventMsg = syncEvent.getSubscriptionSetName(); int eventType = syncEvent.getEventType(); Object listenerInfo = syncEvent.getEventInfo(); Exception e = null; ConflictReader cr = null; if (listenerInfo instanceof Exception)
e = (Exception) listenerInfo;
else if (listenerInfo instanceof ConflictReader)
cr = (ConflictReader) listenerInfo;
// Only ISync.EVT_CFT_REJECT is passed in if (eventType == ISync.EVTTYPE_CONFLICT) {
String tabName = cr.getTableName(); traceln("Conflict table " + tabName); byte rowdata = cr.getRejectedRow(); // Do the right thing with the row data, it was your // client's changes that conflicted in the sync server // and they are about to lose their inventory order.... displayError(eventMsg, e, eventCode); return ISync.RTNCB_DONE;
} // Only the following are passed in: //
    //
  • ISync.EVT_ERR_RECV_REPLY //
  • ISync.EVT_ERR_SEND_REQUEST //
  • ISync.EVT_ERR_SERVER //
if (eventType == ISync.EVTTYPE_ERROR) {
// Error Condition displayError(eventMsg, e, eventCode); traceln(" EVENT : EVENT_ERROR"); ticker.setString("Synchronize Failed"); joinAndShowSchedule(); return ISync.RTNCB_DONE;
} // Only EVTTYPE_INFO remain switch (eventCode) { case ISync.EVT_INF_SYNC_PROG:
syncGauge.setValue(syncEvent.getSyncProgress()); break;
case ISync.EVT_INF_SYNC_STARTED:
syncStateField.setString("Sync Started"); break;
case ISync.EVT_INF_SUBSSET_STARTED:
ticker.setString(eventMsg); break;
case ISync.EVT_INF_PREP_MSG:
syncStateField.setString("Prepare Msg"); break;
case ISync.EVT_INF_SEND_MSG:
syncStateField.setString("Sending Msg"); break;
case ISync.EVT_INF_WAIT_MSG:
syncStateField.setString("Wait on reply"); break;
case ISync.EVT_INF_SYNC_CANCELED:
showAlert("Sync", "Canceled", null, eventCode); // join thread, return to last screen, return RTNCB_DONE if (syncThread != null && syncThread.isAlive()) {
try { syncThread.join(); } catch (java.lang.InterruptedException ie) { }
} syncStateField.setString("Sync Canceled"); display.setCurrent(statusForm); currentForm = statusForm; break;
case ISync.EVT_INF_SYNC_SUCCEEDED:
ticker.setString("Finished Synchronize"); joinAndShowSchedule(); break;
} return ISync.RTNCB_DONE;
}


Field Summary
static java.lang.String CP_1252
          CodePage value for Latin-1 single byte character set
static java.lang.String CP_UTF16
          CodePage value for multi-byte Unicode
 
Method Summary
 boolean acceptsURL(java.lang.String url)
          Tests if this provider supports the specified protocol in the uri.
 java.lang.String base64_Encode(byte[] indata)
           
 void cancelSync()
          User callable cancel of synchronization operation.
 void close()
          Commit sync mode changes to the configuration database and release any open resources.
 com.ibm.mobileservices.isync.ISyncService createSyncService(java.lang.String uri, java.lang.Object propObj)
          Get a synchronization service instance.
 com.ibm.mobileservices.isync.ISyncService createSyncService(java.lang.String host, java.lang.String port, java.lang.String user, java.lang.String password)
          Deprecated.  
 java.lang.String getBuildDate()
          Get the build date of the provider
 java.lang.String getCharEncoding()
          Get the character encoding.
 com.ibm.mobileservices.isync.ISyncConfigStore getConfigStore(java.lang.String unusedPath)
          Get an instance of the configuration store.
 java.lang.String getHost()
          Get server hostname or IP.
static com.ibm.mobileservices.isync.ISyncProvider getInstance()
           
 java.lang.String getPort()
          Get server port.
 java.lang.String getPref(int prefID)
          Get the default value or user specified value of a preference.
 com.ibm.mobileservices.isync.ISyncSubscriptionSet[] getSubscriptionSets()
          Return an array of ISyncSubscriptionSet instances describing all subscription sets available for synchronization.
 com.ibm.mobileservices.isync.ISyncDriver getSyncDriver()
          Get an instance of the synchronization driver.
 com.ibm.mobileservices.isync.midp.TableMetaData getTableMetaDataByName(java.lang.String tableName)
          Look up the table by name in all Subscription Sets, will return null if an initial syncConfig(), sync() has not been performed
 int getVersion()
          Return the version of this product in a 32-bit unsigned integer in the format of 0xMMNNRRXX, where MM, NN, and RR are hexadecimal representation of major, minor, and modification version numbers respectively, and XX is reserved.
 void purge()
          Removes all configuration information and start from initial state.
 void setPref(int prefID, java.lang.String value)
          Set a preference for this synchronization operation.
 void setSyncListener(com.ibm.mobileservices.isync.event.ISyncListener listener)
          User implemented listener implementation to receive events in eventsIssued method
 void setTraceStream(java.io.PrintStream strm)
          Used for QA purposes only, requires Debug.AUTO_DEBUG to be turned on, trace is written to the stream.
 int setup()
           
 int sync()
          Synchronize all subscription sets that are enabled in the ISyncConfigStore.
 int syncConfig()
          Synchronize the configuration to obtain subscription set worklist from the server.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CP_1252

public static final java.lang.String CP_1252
CodePage value for Latin-1 single byte character set

See Also:
Constant Field Values

CP_UTF16

public static final java.lang.String CP_UTF16
CodePage value for multi-byte Unicode

See Also:
Constant Field Values
Method Detail

getInstance

public static com.ibm.mobileservices.isync.ISyncProvider getInstance()

createSyncService

public com.ibm.mobileservices.isync.ISyncService createSyncService(java.lang.String host,
                                                                   java.lang.String port,
                                                                   java.lang.String user,
                                                                   java.lang.String password)
                                                            throws ISyncException
Deprecated.  

Get a synchronization service instance. When the sync driver's sync method is invoked, it will establish a connection to server , on the specified port authenticating with user , and password .

Specified by:
createSyncService in interface ISyncProvider
Parameters:
host - server hostname or IP address
port - port number
user - user ID for authentication with DB2 Everyplace.
password - for authentication with DB2 Everyplace.
Returns:
a new ISyncService instance for use with ISyncConfigStore
Throws:
throws - ISyncException with code:
  • EXC_ILLEGAL_ARG
  • EXC_ILLEGAL_STATE
ISyncException
See Also:
ISyncConfigStore

createSyncService

public com.ibm.mobileservices.isync.ISyncService createSyncService(java.lang.String uri,
                                                                   java.lang.Object propObj)
                                                            throws ISyncException
Get a synchronization service instance. When the sync driver's sync method is invoked, it will establish a connection to uri , authenticating with user , and password obtained from the propObj parameter, an instance of Hashtable.

Specified by:
createSyncService in interface ISyncProvider
Parameters:
uri - schema://server hostname or IP address:portNumber
propObj - Object which is an instance of Hashtable, "isync.user" and "isync.user" are used for the DB2 Everyplace Sync Server authentication. See specific implementations for what properties may be set.
Returns:
a new ISyncService instance for use with ISyncConfigStore
Throws:
throws - ISyncException with code:
  • EXC_ILLEGAL_ARG
  • EXC_ILLEGAL_STATE

An example of how to use the propObj parameter:

Properties prop = new Properties(): prop.put("isync.user", "me"); prop.put("isync.password", "abc"); // For Japanese, Chinese multibyte codepages prop.put("isync.encoding", "UnicodeBig"); prop.put("isync.trace", ISync.TRACE_ON); provider.createSyncService("http://myhost:90", prop);

Supported encodings are:

  • "2252" - All single byte character sets.
  • "UnicodeBig" - Single and double byte character sets.
ISyncException
See Also:
ISyncConfigStore

getBuildDate

public java.lang.String getBuildDate()
                              throws ISyncException
Get the build date of the provider

Specified by:
getBuildDate in interface ISyncProvider
Returns:
a String specifying the build date
Throws:
ISyncException

getConfigStore

public com.ibm.mobileservices.isync.ISyncConfigStore getConfigStore(java.lang.String unusedPath)
Get an instance of the configuration store. Instantiate a ISyncConfigStore instance, any persistent configuration information is read when ISyncConfigStore is created, if none is present, the Config is left in the same state as if config.purge() had been called.

Specified by:
getConfigStore in interface ISyncService
Parameters:
unusedPath - not used in this implementation.
Returns:
The new instance.

getHost

public java.lang.String getHost()
Get server hostname or IP.

Specified by:
getHost in interface ISyncService
Returns:
string value of host

getPort

public java.lang.String getPort()
Get server port.

Specified by:
getPort in interface ISyncService
Returns:
string value of port

getCharEncoding

public java.lang.String getCharEncoding()
                                 throws ISyncException
Get the character encoding.

Specified by:
getCharEncoding in interface ISyncService
Returns:
String value of the encoding.
Throws:
ISyncException

getSyncDriver

public com.ibm.mobileservices.isync.ISyncDriver getSyncDriver()
Get an instance of the synchronization driver.

Specified by:
getSyncDriver in interface ISyncConfigStore
See Also:
ISyncDriver

getSubscriptionSets

public com.ibm.mobileservices.isync.ISyncSubscriptionSet[] getSubscriptionSets()
Return an array of ISyncSubscriptionSet instances describing all subscription sets available for synchronization.

Specified by:
getSubscriptionSets in interface ISyncConfigStore
Returns:
array of ISyncSubscriptionSets
See Also:
ISyncSubscriptionSet

purge

public final void purge()
Removes all configuration information and start from initial state.

Specified by:
purge in interface ISyncConfigStore

getVersion

public final int getVersion()
Return the version of this product in a 32-bit unsigned integer in the format of 0xMMNNRRXX, where MM, NN, and RR are hexadecimal representation of major, minor, and modification version numbers respectively, and XX is reserved.

To decode:

int version = isync.getVersion();
int major = (version & 0xff000000) >> 24;
int minor = (version & 0x00ff0000) >> 16;
int mod = (version & 0x0000ff00) >> 8;

Specified by:
getVersion in interface ISyncProvider
Returns:
Version number of this ISync Java API.

close

public final void close()
Commit sync mode changes to the configuration database and release any open resources.

Configuration information is persisted on each sync/syncConfig request. In is only critical to call close(), for persistince of the configuration information if the application changed subscription set state after the sync.

Note: close() must be called to commit any mode settings made to subscription sets after a sync completed.

Specified by:
close in interface ISyncDriver

syncConfig

public final int syncConfig()
                     throws ISyncException
Synchronize the configuration to obtain subscription set worklist from the server.

Specified by:
syncConfig in interface ISyncDriver
Returns:
  • RTN_SUCCEEDED
  • RTN_CANCELED
  • RTN_FAILED

Return status descriptions:

  • RTN_SUCCEEDED: Configuration synchronized successfully.
  • RTN_CANCELED: The synchronization has been canceled.
  • RTN_FAILED: Configuration sync has failed to synchronize.
Throws:
throws - ISyncException with code:
  • EXC_NET_RESOLVE_HOST
  • EXC_AUTH_FAILED
  • EXC_INVALID_SESSION
  • EXC_INCOMP_VERSION
ISyncException

sync

public final int sync()
               throws ISyncException
Synchronize all subscription sets that are enabled in the ISyncConfigStore.

The sync method launches a synchronization session based on the ISyncConfigStore object used to create the ISyncDriver instance (ISyncDriver isync = config.getSyncDriver()).

Initially, a subscription set is said to be in RESET mode, if it has never been synchronized before. When the sync engine performs synchronization on that subscription set, it will fetch a complete replica from the SyncServer, which is called a REFRESH operation.

After the refresh is completed, next time when the subscription set is synchronized again, the sync engine will simply synchronize the changed data, which is called a SYNC operation.

The sync engine always synchronizes the configuration first, if it failed, it will not continue with the subsequent subscription sets. The whole synchronization session simply stops.

On non-MIDP clients: If the sync engine failed on one subscription set (not the configuration), it will still continue with others, if any. The return code is basically the aggregate of the sync status for all the subscription sets the sync engine has synchronized.

MIDP Clients that fail during a synchronization should attempt another sync which will attempt to pick up after the point of failure. For example, if the phone client loses reception, they can retry up to a limit (30 minutes by default) established by the Sync Server administrator. If this restart fails, the client must REFRESH all data again.

Specified by:
sync in interface ISyncDriver
Returns:
  • RTN_SUCCEEDED
  • RTN_CANCELED
  • RTN_FAILED

Return status descriptions:

  • RTN_SUCCEEDED: All subscription sets synchronized successfully.
  • RTN_CANCELED: The synchronization has been canceled.
  • RTN_FAILED: One or more subscription set(s) has failed to sync. If the config (the very first subscription set) fails to sync, the entire synchronization session is aborted. If one of the subscriptions in a subscription set fails to sync (due to conflicting data sent from this client in a previous sync session), the sync engine will skip to the next subscription set.
Throws:
throws - ISyncException with code:
  • EXC_NET_RESOLVE_HOST
  • EXC_AUTH_FAILED
  • EXC_INVALID_SESSION
  • EXC_INCOMP_VERSION
ISyncException

setSyncListener

public final void setSyncListener(com.ibm.mobileservices.isync.event.ISyncListener listener)
User implemented listener implementation to receive events in eventsIssued method

Specified by:
setSyncListener in interface ISyncDriver

getTableMetaDataByName

public com.ibm.mobileservices.isync.midp.TableMetaData getTableMetaDataByName(java.lang.String tableName)
Look up the table by name in all Subscription Sets, will return null if an initial syncConfig(), sync() has not been performed

Returns:
schema information in a TableMetaData instance
See Also:
syncConfig(), sync()

cancelSync

public final void cancelSync()
User callable cancel of synchronization operation. The C version is quite different than our current Java version.

Specified by:
cancelSync in interface ISyncDriver

getPref

public java.lang.String getPref(int prefID)
                         throws ISyncException
Get the default value or user specified value of a preference. See setPref .

See ISyncPref for legal values

Specified by:
getPref in interface ISyncDriver
Parameters:
prefID - an int specifying the preference ID
Returns:
a String specifying the preference value; returns null if not found.
Throws:
throws - ISyncException with code of :
  • EXC_PREF_UNKNOWN_ID
ISyncException
See Also:
ISyncDriver.setPref(int, java.lang.String)

setPref

public final void setPref(int prefID,
                          java.lang.String value)
                   throws ISyncException
Set a preference for this synchronization operation.

The set of preferences which must be specified is)

Specified by:
setPref in interface ISyncDriver
Throws:
throws - ISyncException with code of:
  • EXC_PREF_UNKNOWN_ID
ISyncException

setTraceStream

public void setTraceStream(java.io.PrintStream strm)
Used for QA purposes only, requires Debug.AUTO_DEBUG to be turned on, trace is written to the stream.


acceptsURL

public boolean acceptsURL(java.lang.String url)
Description copied from interface: ISyncProvider
Tests if this provider supports the specified protocol in the uri. e.g. isync:db2j:, isync:db2e:

Specified by:
acceptsURL in interface ISyncProvider
Parameters:
url - a String uri
Returns:
true if the provider supports the protocol; false otherwise

base64_Encode

public java.lang.String base64_Encode(byte[] indata)
                               throws java.io.IOException
java.io.IOException

setup

public int setup()
          throws ISyncException
ISyncException


(c) Copyright IBM Corp. 2001, 2002, 2003. All Rights Reserved.