⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mailsyncsource.java

📁 moblie syncml mail javame
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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.syncml;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Date;

import com.funambol.mailclient.ui.controller.MailSyncListener;
import com.funambol.mailclient.mm.MessageManager;

import com.funambol.syncml.client.BaseSyncSource;
import com.funambol.syncml.protocol.SyncML;
import com.funambol.syncml.protocol.SyncMLStatus;
import com.funambol.syncml.spds.SourceConfig;
import com.funambol.syncml.spds.SyncItem;
import com.funambol.syncml.spds.SyncException;

import com.funambol.mail.Folder;
import com.funambol.mail.Message;
import com.funambol.mail.MessageFlags;
import com.funambol.mail.Store;
import com.funambol.mail.StoreFactory;
import com.funambol.mail.MailException;

import com.funambol.util.Log;
import com.funambol.util.XmlException;



/**
 * An implementation of the <i>SyncSource</i> interface, used to send
 * and receive email over the SyncML protocol.
 *
 */
public class MailSyncSource extends BaseSyncSource {
    
    public static final String FOLDER_TYPE = "application/vnd.omads-folder+xml";
    public static final String EMAIL_TYPE = "application/vnd.omads-email+xml";
    
    //--------------------------------------------------------------- Attributes
    
    /** Reference to the mail store */
    private Store store;
    /** A global status code for the MailSyncSource */
    private int mailSourceStatus;
    /** Flag used to mark the beginning of the receiving phase */
    private boolean receiving;

    private boolean isFirstAddCommand;
    
    //------------------------------------------------------------- Constructors
    
    /**
     * MailSyncSource constructor: initialize source config and
     * init all the rest to null. The real initialization is done by
     * the beginSync method.
     */
    public MailSyncSource(SourceConfig config) {
        super(config);
        
        isFirstAddCommand = true;
        
        store = StoreFactory.getStore();
        globalStatus = STATUS_SUCCESS;
        receiving = false;
    }
    
    //----------------------------------------------------------- Public Methods
    
    /**
     * Called after SyncManager preparation and initialization just before start
     * the synchronization of the SyncSource.
     *
     * @param syncMode the synchronization type: one of the values in
     *                 sync4j.framework.core.AlertCode
     *
     * @throws SyncException in case of error. This will stop the sync process
     */
    public void beginSync(int syncMode) throws SyncException {
        super.beginSync(syncMode);      // call BaseSyncSource.beginSync()
        
        globalStatus = STATUS_SUCCESS;
        receiving = false;
    }

    private void resetMailStore() throws SyncException {
        // Remove local mail in INBOX
        try {
            
            store.removeFolder(store.INBOX);
            store.createFolder(store.INBOX);
        } catch(MailException se) {
            Log.error("[MailSyncSource.beginSync]:"+se.toString());
            throw new SyncException(SyncException.CLIENT_ERROR, "Error cleaning local mail: " +se.toString());
        }
    }

    /**
     * Called just before committing the synchronization process by the
     * SyncManager. The SyncSource can stop the commit phase raising an
     * exception here.
     *
     * @throws SyncException in case of error, to stop the commit.
     */
    public void endSync() throws SyncException  {
        super.endSync();        // call BaseSyncSource.endSync()   
    }
    
    /**
     * Add a new item from the server to the mail store.
     */
    public int addItem(SyncItem item) throws SyncException {
        Log.info("New item " + item.getKey() + " from server.");

        if ((syncMode==SyncML.ALERT_CODE_SLOW
            ||syncMode==SyncML.ALERT_CODE_REFRESH_FROM_SERVER)
            &&isFirstAddCommand) {
            
            Log.debug("[MSS] Resetting Mail Store Before adding the first item");
            resetMailStore();
            FlagQueue.clear();
            Log.debug("[MSS] Mail Store reset");
            isFirstAddCommand=false;
            Log.debug("[MSS] isFirstAddCommand set to: " + isFirstAddCommand);
            
        }
        
        if(item.getType().equals(EMAIL_TYPE)) {
            // Parse the mail item
            Log.debug("Email item");

            int errorCode;
            try {
                MessageManager mm = MessageManager.getInstance();
                Message msg = mm.createNewMessage(item.getParent(),
                                                  item.getKey(),
                                                  item.getContent());
                Log.debug("message created");
                if (msg != null) {
                    item.setKey(msg.getKey());
                    item.setClientRepresentation(msg);
                    errorCode = SyncMLStatus.SUCCESS;
                } else {
                    Log.info("[MailSyncSource.addItem()] Invalid empty email data from item " + 
                            item.getKey() );
                    globalStatus = STATUS_SERVER_ERROR;
                    errorCode = SyncMLStatus.GENERIC_ERROR;
                }
            } catch (Exception e) {
                Log.error(this,"[addItem]Error saving message: " + item.getKey() 
                            + " " + e.toString() );
                
                e.printStackTrace();
                // TODO: implement a finer handling of the exception?
                globalStatus = STATUS_RECV_ERROR;
                errorCode = SyncMLStatus.GENERIC_ERROR;
            }
            return errorCode;
            
        } else if(item.getType().equals(FOLDER_TYPE)) {
            // Parse the mail item
            Log.debug("Folder item");
            MessageManager mm = MessageManager.getInstance();
            try {
                // For the moment, the client does not create
                // other folders on server's request, just checks
                // the commands to return the correct status
                // and key
                Folder folder = mm.createFolder(item.getContent());
                item.setKey(folder.getName());
                return SyncMLStatus.SUCCESS;
            } catch (XmlException xe) {
                Log.error("Error parsing item: " + item.getKey());
                // Return error to the server
                globalStatus = SyncMLStatus.GENERIC_ERROR;
                return SyncMLStatus.GENERIC_ERROR;
            }
        } else {
            Log.error(this,"[addItem] Unknown item type: "
                    + item.getType());
            globalStatus |= STATUS_RECV_ERROR;
            return SyncMLStatus.GENERIC_ERROR;
        }
    }
    
    /** Update a given SyncItem stored on the source backend */
    public int updateItem(SyncItem item) throws SyncException {
        Log.info("Updated item " + item.getKey() + " from server.");

        if(item.getType().equals(EMAIL_TYPE)) {
            // Parse the mail item
            Log.debug("Email item");

            MessageManager mm = MessageManager.getInstance();
            int errorCode;
            try {
                MessageFlags flags = mm.updateMessageFlags(item.getParent(),
                                                           item.getKey(),
                                                           item.getContent());
                item.setClientRepresentation(flags);
                errorCode = SyncMLStatus.SUCCESS;
            } catch (Exception e) {
                Log.error(this, "Error updating message flags " + e.toString());
                globalStatus = STATUS_RECV_ERROR;
                errorCode = SyncMLStatus.GENERIC_ERROR;
            }
            return errorCode;
        } else if(item.getType().equals(FOLDER_TYPE)) {
            // Parse the mail item
            Log.debug("Folder item update: ignored");
            return SyncMLStatus.SUCCESS;
        } else {
            //Log.info("[MailSyncSource.updateItem] Unexpected item type"+ item.getType());
            Log.error(this, "[MailSyncSource.updateItem] Unexpected item type"+ item.getType());
            globalStatus |= STATUS_RECV_ERROR;
            return SyncMLStatus.GENERIC_ERROR;
        }
    }
    
    /** Delete a SyncItem stored on the related Items list */
    public int deleteItem(String key) throws SyncException {
        Log.info("Delete from server for item " + key);

        try {
            Log.debug("[deleteItem]Email item");
            MessageManager mm = MessageManager.getInstance();
            mm.deleteMessage(key);
            return SyncMLStatus.SUCCESS;
        } catch (MailException me) {
            Log.error(this,"Error removing message: " + key+ " " + me.toString() );
            globalStatus = STATUS_RECV_ERROR;
            return SyncMLStatus.GENERIC_ERROR;
        }
    }
    
    /**
     * Tell the SyncSource the status returned by the server
     * for an Item previously sent.
     *
     * @param key the key of the item
     * @param status the status code received for that item
     *
     * @throws SyncException if the SyncSource wants to stop the sync
     */
    public void setItemStatus(String key, int status)
    throws SyncException {
        Log.info("Status " + status + " for item " + key + " from server.");
        try {
            MessageManager mm = MessageManager.getInstance();
            String folder = mm.folderFromKey(key);
            
            if(Store.OUTBOX.equals(folder)) {
                if (SyncMLStatus.isSuccess(status)) {
                    mm.messageEffectivelySent(key);
                } else {
                    globalStatus = STATUS_SEND_ERROR;
                    // TODO: send an event to the client?
                }

⌨️ 快捷键说明

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