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 + -
显示快捷键?