syncclient.java

来自「moblie syncml mail javame」· Java 代码 · 共 765 行 · 第 1/2 页

JAVA
765
字号
/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

package com.funambol.mailclient.sm;

import com.funambol.mailclient.config.ConfigException;
import com.funambol.mailclient.config.ConfigManager;
import com.funambol.mailclient.Account;
import com.funambol.mailclient.sm.SyncClientConfig;
import com.funambol.mailclient.syncml.ContactSyncSource;
import com.funambol.mailclient.syncml.MailSyncSource;
import com.funambol.mailclient.syncml.MailSyncFilter;
import com.funambol.mailclient.syncml.MessageSyncSource;
import com.funambol.mailclient.MailFilter;
import com.funambol.mailclient.ui.controller.UIController;
import com.funambol.mailclient.ui.controller.MailSyncListener;
import com.funambol.mailclient.ui.controller.ContactSyncListener;
import com.funambol.mailclient.ui.controller.MailSyncSingleMessageListener;
import com.funambol.syncml.protocol.SyncML;
import com.funambol.syncml.spds.SourceConfig;
import com.funambol.syncml.spds.SyncConfig;
import com.funambol.syncml.spds.SyncException;
import com.funambol.syncml.spds.CompressedSyncException;
import com.funambol.syncml.spds.SyncManager;
import com.funambol.syncml.spds.SyncSource;
import com.funambol.util.Log;
import com.funambol.util.SyncListener;
import com.funambol.util.ThreadPool;

import com.funambol.mail.Message;

import java.io.IOException;


/**
 * A class that control and unify the sync process on the client side
 */
public class SyncClient implements Runnable {
    /**
     * SyncManager class declaration:
     * managed by a Singleton pattern in order to avoid memory leaks and
     * manage concurrent sync processes
     */
    private SyncManager sm;

    /** Source configuration */
    private SourceConfig sc;

    /** Instance of mail listener */
    private MailSyncListener mailListener;

    /** Instance of contactl listener */
    private ContactSyncListener contactListener;

    /** Instance of single message listener */
    private MailSyncSingleMessageListener singleMessageListener;

    /** Instance of this class*/
    private static SyncClient instance;

    // Constants that identify repositories that can be synchronized
    // This order is also the order in which the repositories are synchronized
    // when multiple repositories are requested for syncing. We always want the
    // messages to be first so the user has a faster response
    /** Constant that identifies MESSAGES repository */
    public static final int MESSAGES = 0;
    /** Constant that identifies CONTACTS repository */
    public static final int CONTACTS = 1;

    private static final int LAST_REP_ID = 1;

    /** Specifies which repositories need to be synchronized */
    private boolean repositoriesEnabled[];
    /** Specifies repositories synch mode */
    private int repositoriesSyncMode[];

    /** Specifies that a singleMsgSrc sync needs to be performed on this
     * source */
    private MessageSyncSource singleMsgSrc;

    /** Indicates if the SyncClient is busy (sync already in progress) */
    private boolean isBusy;

    /** Device User Agent used in HTTP headers */
    private String deviceUA;

    private int numRepositories;


    /**
     * Default (private) constructor:
     */
    private SyncClient() {

        reset();
    }

    ///////////////////////// Public methods /////////////////////////////////

    /**
     * This method returns the only SyncClient instance in the system. This
     * SyncClient is always associated to the default mail account that
     * is returned by the ConfigManager.
     */
    public static SyncClient getSyncClient() {

        if (instance == null) {
            instance = new SyncClient();
        }
        return instance;
    }



    /**
     * This method fires the synchronization of single repository.
     * This method cannot be invoked if a synchronization is already on going.
     * It is up to the client to verify this, for example by invoking the isBusy
     * method. If the method gets invoked when a synchronization is on going
     * then a SyncException is thrown.
     * This methods can only be invoke once a valid configuration has been
     * set, otherwise a ConfigException is thrown.
     * This method is non blocking and the synchronization is performed by a
     * separate thread. The client is notified trhough the SyncListener which is
     * linked to the SyncSource that is being synchronized.
     *
     * @param repository specifies the repository to sync
     *
     */
    public void sync(int repository) {

        resetRepState();
        repositoriesEnabled[repository]  = true;
        repositoriesSyncMode[repository] = -1;
        startThread();
    }

    /**
     * This method fires the synchronization of a single repository, allowing
     * the user to override the source default mode.
     * This method cannot be invoked if a synchronization is already on going.
     * It is up to the client to verify this, for example by invoking the isBusy
     * method. If the method gets invoked when a synchronization is on going
     * then a SyncException is thrown.
     * This methods can only be invoke once a valid configuration has been
     * set, otherwise a ConfigException is thrown.
     * This method is non blocking and the synchronization is performed by a
     * separate thread. The client is notified trhough the SyncListener which is
     * linked to the SyncSource that is being synchronized.
     *
     * @param repository specifies the repository to sync
     * @param mode synchronization mode
     *
     */
    public void sync(int repository, int mode) {

        resetRepState();
        repositoriesEnabled[repository]  = true;
        repositoriesSyncMode[repository] = mode;
        startThread();
    }

    /**
     * This method synchronizes all the known repositories, using sources
     * default sync mode.
     * This method cannot be invoked if a synchronization is already on going.
     * It is up to the client to verify this, for example by invoking the isBusy
     * method. If the method gets invoked when a synchronization is on going
     * then a SyncException is thrown.
     * This methods can only be invoke once a valid configuration has been
     * set, otherwise a ConfigException is thrown.
     * This method is non blocking and the synchronization is performed by a
     * separate thread. The client is notified trhough the SyncListener which is
     * linked to the SyncSource that is being synchronized.
     *
     */
    public void sync() {

        resetRepState();
        repositoriesEnabled[CONTACTS]  = true;
        repositoriesSyncMode[CONTACTS] = -1;
        repositoriesEnabled[MESSAGES]  = true;
        repositoriesSyncMode[MESSAGES] = -1;
        startThread();
    }

    /**
     * This method fires synchronizations for one or more repositories,
     * using sources default sync mode.
     * This method cannot be invoked if a synchronization is already on going.
     * It is up to the client to verify this, for example by invoking the isBusy
     * method. If the method gets invoked when a synchronization is on going
     * then a SyncException is thrown.
     * This methods can only be invoke once a valid configuration has been
     * set, otherwise a ConfigException is thrown.
     * This method is non blocking and the synchronization is performed by a
     * separate thread. The client is notified trhough the SyncListener which is
     * linked to the SyncSource that is being synchronized.
     *
     * @param repositories repositories to be synchronized
     */
    public void sync(int repositories[]) {

        resetRepState();
        // We do not catch ArrayOutOfBounds and if it occour we let it
        // raise
        for(int i=0; i<repositories.length;++i) {

            int repository = repositories[i];
            repositoriesEnabled[repository]  = true;
            repositoriesSyncMode[repository] = -1;
        }
        startThread();
    }


    /**
     * This method fires synchronizations for one or more repositories, allowing
     * the client to overried source default sync mode.
     * If multiple synchronizations are requested, then they are executed
     * sequentially and the order is unspecified.
     * These methods cannot be invoked if a synchronization is already on going.
     * It is up to the client to verify this, for example by invoking the isBusy
     * method. If the method gets invoked when a synchronization is on going
     * then a SyncException is thrown.
     * Theise methods can only be invoke once a valid configuration has been
     * set, otherwise a ConfigException is thrown.
     * This method is non blocking and the synchronization is performed by a
     * separate thread. The client is notified trhough the SyncListener which is
     * linked to the SyncSource that is being synchronized.
     *
     * @param repositories list of objects to be synchronized
     * @param mode syncronization mode
     *
     */
    public void sync(int repositories[], int modes[]) {

        resetRepState();
        // Synchronize all the objects requested by the client
        for(int i=0;i<repositories.length;++i) {
            int repository = repositories[i];
            int mode       = modes[i];

            repositoriesEnabled[repository]  = true;
            repositoriesSyncMode[repository] = mode;
        }
        startThread();
    }

    /**
     * Sync a single message. Messages are identified by an ID
     * which is composed by "folder" + "msgId". The client can specify if
     * attachments should be retrieved or not.
     * Today this method is mainly intended for the getFullMessage
     * functionality.
     * This method is non blocking and the synchronization is performed by a
     * separate thread. The client is notified trhough the SyncListener which is
     * linked to the SyncSource that is being synchronized.
     *
     * @param folder folder the message belongs to
     * @param luid   local id (LUID) of the message
     * @param withAttachments specifies if attachments must be included in the
     *                        message.
     *
     * @throws SyncException if there is already a synchronization in progess or
     *                       if something goes wrong during the sync
     * @throws ConfigException if there is no valid configuration for the
     *                         synchronization to be performed
     */
    public synchronized void syncSingleMessage(String folder, String luid,
            boolean withAttachments)
            throws ConfigException {

        // Perform the message sync
        MailSyncFilter inclusive = new MailSyncFilter(luid);
        inclusive.enableAttachmentsDownload(withAttachments);

        SourceConfig srcCfg = loadSourceConfig(SourceConfig.MAIL,
                SourceConfig.EMAIL_OBJECT_TYPE,
                "mail");
        singleMsgSrc = new MessageSyncSource(srcCfg, inclusive);
        singleMsgSrc.setListener(singleMessageListener);
        startThread();
    }

    /**
     * Set a listener on the mail sync source, used to signal the calling thread
     * of the relevant events occurred during mail synchronization.
     *
     * @param listener the SyncListener to set, or null to remove
     *                 the listener
     */
    public void setMailListener(MailSyncListener listener) {

        mailListener = listener;
    }

    /**
     * Set a listener on the contact sync source, used to signal the calling
     * thread of the relevant events occurred during contacts synchronization.
     *
     * @param listener the SyncListener to set, or null to remove
     *                 the listener
     */
    public void setContactListener(ContactSyncListener listener) {

        contactListener = listener;
    }

    /**
     * Set a listener on the single message sync source, used to signal the calling
     * thread of the relevant events occurred during single msg synchronization.
     *
     * @param listener the SyncListener to set, or null to remove
     *                 the listener
     */
    public void setSingleMessageListener(MailSyncSingleMessageListener listener) {

        singleMessageListener = listener;
    }

    /**
     * Factory method for the SourceConfig.
     * Loads and return the correct SouorceConfig depending on the source name.
     *
     * @param name the source name
     * @param type the source type
     * @param remoteUri the remore URI for the source
     */
    public SourceConfig loadSourceConfig(String name, String type,
            String remoteUri) {

        // create a new SourceConfig with the given paramenters
        sc = new SourceConfig(name, type, remoteUri);
        // The sources used by the mail client are all not encoded.
        sc.setEncoding(SyncSource.ENCODING_NONE);
        // Load the config from RMS.
        try {
            ConfigManager.load("source." + sc.getName(), sc);
            sc.setRemoteUri(remoteUri);
            Log.debug("Config for source" + sc.getName() + " loaded.");
        } catch(ConfigException ce) {
            Log.info("Config for [source: " + sc.getName() + ", uri: " +
                    remoteUri + "] not found, save default.");
            try {
                ConfigManager.save("source." + sc.getName(), sc);
            } catch (Exception e) {
                Log.error("loadSourceConfig, can't save default conf.");
                Log.error(" source: "+sc.getName()+" error: "+e.toString());
            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?