syncclient.java
来自「moblie syncml mail javame」· Java 代码 · 共 765 行 · 第 1/2 页
JAVA
765 行
} catch (IOException ex) {
ex.printStackTrace();
Log.error("loadSourceConfig: "+ex.toString());
}
return sc;
}
/**
* Save the given source config.
*
* @param sc the MailSourceConfig to save.
*
* @throws ConfigException if the config is not present
* @throws IOException if an error occurred during the deserialization
*/
public void saveSourceConfig()
throws ConfigException, IOException {
// The source config is stored in a record named "source.<sourcename>"
ConfigManager.save("source." + sc.getName(), sc);
Log.info("[SyncClient] config for source " + sc.getName() + " saved.");
}
/**
* Check if a synchronization is in progress. SyncClient allows a sync at a
* time. If one of the sync methods is invoked while synchronizing, then an
* exception is thrown, but the client can check if a sync is in progress a
* priori by using this method.
* TODO FIXME: this mechanism is not thread safe
*/
public boolean isBusy() {
return isBusy;
}
/**
* This method is the entry poin for the thread that performs the
* synchronization. The user should never create the thread but he
* should rely on the sync methods that spawn a thread for a non blocking
* synchronization
*/
public void run() {
// If a synchronization is already in progress, then an exception is
// thrown
if (isBusy) {
Log.info("[sync] sync already in progress.");
throw new SyncException(
SyncException.CONCURRENCE_ERROR, "Sync in progress");
}
// Dump memory stats
Log.stats("Beginning of SyncClient.run");
numRepositories = 0;
Log.info("- SyncClient: Start Sync -");
long start = System.currentTimeMillis();
// TODO FIXME: This is not thread safe
isBusy = true;
try {
// At this point a configuration must be available, if not a
// ConfigException gets propagated
// Get the sync account
Account a = ConfigManager.getConfig().getMailAccount();
// We recreate a SyncManager at any sync, because we trade memory for
// performance
sm = getSyncManager(a);
if (singleMsgSrc != null) {
// In this case we must perform a single message sync, which is done
// when the user wants to retrieve a full message
Log.info("*** Separate thread for Sync of single message in progress ***");
sm.sync(singleMsgSrc, SyncML.ALERT_CODE_ONE_WAY_FROM_SERVER);
//save sync source configuration
saveSourceConfig();
} else {
// This is the sync of complete repositories
Log.info("*** Separate thread for Sync of repositories in progress ***");
// Count the number of repositories to be synchronized
for(int i=0;i<LAST_REP_ID+1;++i) {
if (repositoriesEnabled[i]) {
numRepositories++;
}
}
// Notify startMultiSession events
if (numRepositories > 1) {
for(int i=0;i<LAST_REP_ID+1;++i) {
if (repositoriesEnabled[i]) {
if (i == MESSAGES) {
if (mailListener != null) {
mailListener.startMultiSession(repositoriesEnabled);
}
} else if (i == CONTACTS) {
if (contactListener != null) {
contactListener.startMultiSession(repositoriesEnabled);
}
}
}
}
}
// Synchronize the repositories
for(int i=0;i<LAST_REP_ID+1;++i) {
if (repositoriesEnabled[i]) {
syncRepository(i, repositoriesSyncMode[i]);
}
}
}
} catch (CompressedSyncException e) {
Log.error(this, "Sync failed because compression failed");
isBusy = false;
// disable only-in-memory property for compression
ConfigManager._tmpCompress = false;
runUncompressedSync();
} catch (SyncException se) {
Log.error(this, "Sync failed because SyncManager failed");
releaseResources();
throw se;
} catch(ConfigException ce) {
Log.error(this, "Sync failed because source state cannot be saved");
Log.error(this, ce.toString());
releaseResources();
throw new SyncException(
SyncException.STORAGE_ERROR,
"Error saving source state:" + ce.toString());
} catch(IOException ioe) {
Log.error(this, "Sync failed because source state cannot be saved");
Log.error(this, ioe.toString());
releaseResources();
throw new SyncException(
SyncException.STORAGE_ERROR,
"Error saving source state:" + ioe.toString());
} finally {
// Notify endMultiSession events
if (numRepositories > 1) {
for(int i=0;i<LAST_REP_ID+1;++i) {
if (repositoriesEnabled[i]) {
if (i == MESSAGES) {
if (mailListener != null) {
mailListener.endMultiSession();
}
} else if (i == CONTACTS) {
if (contactListener != null) {
contactListener.endMultiSession();
}
}
}
}
}
long syncTime = System.currentTimeMillis() - start;
Log.info("Sync Time: " + (syncTime/1000));
Log.info("- End Sync -");
releaseResources();
// Dump memory stats
Log.stats("End of SyncClient.run");
}
}
private void runUncompressedSync() {
run();
}
private void releaseResources() {
singleMsgSrc = null;
// Reset the reference to the SyncManager to allow the GC to collect
// memory if it needs to do so
sm = null;
isBusy = false;
numRepositories = 0;
}
public String getDeviceUA() {
if (deviceUA==null) {
deviceUA = createUserAgent();
}
return deviceUA;
}
///////////////////////// Private methods ////////////////////////////////
/*
* This method starts a synchronization thread. The syncs to be performed
* have been set up by one of the corresponding sync methods.
*/
private void startThread() {
Log.debug("Thread for sync is starting");
UIController.getThreadPool().startThread(this);
}
/**
* This method resets the SyncClient and brings it to an empty state
*/
private void reset() {
sm = null;
sc = null;
mailListener = null;
singleMsgSrc = null;
isBusy = false;
repositoriesEnabled = new boolean[LAST_REP_ID + 1];
repositoriesSyncMode = new int[LAST_REP_ID + 1];
resetRepState();
}
/**
* This method resets the repositories information. In particular the
* information about which repositories need to be synced and their syncmode
*/
private void resetRepState() {
for(int i=0;i<LAST_REP_ID+1;++i) {
repositoriesEnabled[i] = false;
repositoriesSyncMode[i] = -1;
}
}
/**
* Set a filter on the underlying MailSyncSource. This method
* must be called on an open connection only.
* The filter is lost after a close() call.
*
* @param MailFilter the filter to apply, or null to remove it
* @throws MailClientException if the connection is not open
*/
private void setFilter(MailSyncSource ss, MailFilter filter)
throws SyncException {
// Nullify the filter if the source is present, ignore otherwise
if (filter == null) {
if(ss != null) {
ss.setFilter(null);
}
return;
}
// Throw an exception if the source is not initialized yet
if(ss == null) {
Log.error(this, "Can't set a filter on a closed connection.");
throw new SyncException(SyncException.CLIENT_ERROR,"Must be connected to set a filter");
}
// Set the source filter
MailSyncFilter sf = new MailSyncFilter(filter);
ss.setFilter(sf);
}
/**
* Helper method used to synchronize a single repository, allowing the
* client to override the sync mode defined in the sync source.
* An appropriate SyncSource is created, depending on the repository that
* needs to be synchronized. Then the synchronization is fired by invoking
* the SyncManager sync method. If everything is OK then the configuration
* is saved.
*
* @param repository identifies the repository to be synchronized
* @param mode allows overwriting of the source default mode (-1 implies the
* usage of the source default mode)
*
* @throws SyncException if something goes wrong during synchronization
* @throws ConfigException if the SyncManager cannot be instantiated because
* the configuration is invalid.
*/
private void syncRepository(int repository, int mode)
throws SyncException, ConfigException, IOException {
SourceConfig srcCfg;
SyncSource source;
// Get the sync account
Account a = ConfigManager.getConfig().getMailAccount();
if (repository == MESSAGES) {
Log.info("SyncClient: synchronizing messages ");
srcCfg = loadSourceConfig(SourceConfig.MAIL,
SourceConfig.EMAIL_OBJECT_TYPE,
a.getRemoteURI());
MailSyncSource ms = new MailSyncSource(srcCfg);
if (mailListener != null)
ms.setListener(mailListener);
source = ms;
setFilter(ms, ConfigManager.getConfig().getMailFilter());
} else if (repository == CONTACTS) {
Log.info("SyncClient: synchronizing contacts ");
srcCfg = loadSourceConfig(SourceConfig.CONTACT,
SourceConfig.VCARD_TYPE,
a.getPimRemoteURI());
ContactSyncSource ss = new ContactSyncSource(srcCfg);
if (contactListener != null)
ss.setListener(contactListener);
source = ss;
} else {
Log.error(this,"Unknown object to sync" );
throw new SyncException(SyncException.CLIENT_ERROR, "Unknown object to sync");
}
Log.info("Source: "+source.getName());
Log.info("SyncMode: "+source.getSyncMode());
//do sync
if (mode != -1) {
sm.sync(source, mode);
} else {
sm.sync(source);
}
//save sync source configuration
saveSourceConfig();
}
private SyncManager getSyncManager(Account a) {
// Init a SyncConfig with the parameters get from Account
SyncConfig syncConfig = new SyncConfig();
syncConfig.syncUrl = a.getUrl();
syncConfig.userName = a.getUser();
syncConfig.password = a.getPassword();
syncConfig.userAgent = createUserAgent();
//#ifdef http_resp.force_cookies
//# syncConfig.forceCookies = true;
//#endif
Log.info("HTTP Device-Agent header: " + syncConfig.userAgent);
// Get SyncClientConfig for Syncml specific parameters
SyncClientConfig conf = new SyncClientConfig();
try {
ConfigManager.load(SyncClientConfig.CONFIGNAME, conf);
} catch (Exception ce) {
Log.info("[getSyncManager] Error reading SyncClientConfig, using defaults.");
// Get a new device Id, it's the first use of the client
// on the device.
conf.generateDeviceId();
}
// Set device id in the devinfo config class
syncConfig.deviceConfig.devID = conf.getDeviceId();
syncConfig.lastServerUrl = conf.getLastSyncUrl();
conf.setLastSyncUrl(syncConfig.syncUrl);
// TODO: check exception handling!!!!!!!!!
try {
// set if the communications with the server must be compressed
//syncConfig.compress = ConfigManager.getConfig().isCompress();
syncConfig.compress = ConfigManager._tmpCompress;
// Get a new instance of SyncManager
sm = new SyncManager(syncConfig);
ConfigManager.save(SyncClientConfig.CONFIGNAME, conf);
} catch (Exception e) {
Log.error("[getSyncManager] Error saving SyncClientConfig Config: " + e.toString());
}
return sm;
}
// Creates UserAgent to use in HTTP requests
private String createUserAgent() {
StringBuffer sbAgent = new StringBuffer();
sbAgent.append(ConfigManager.getClientName() + " Java Mail");
sbAgent.append(" v. ").append(ConfigManager.getClientVersion());
return sbAgent.toString();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?