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

📄 flagqueue.java

📁 moblie syncml mail javame
💻 JAVA
字号:
/*
 * 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 com.funambol.mail.MessageFlags;
import com.funambol.storage.ComplexSerializer;
import com.funambol.storage.ObjectStore;
import com.funambol.storage.Serializable;
import com.funambol.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import com.funambol.storage.AbstractRecordStore;
import javax.microedition.rms.RecordStoreException;

/**
 * A class to store deleted/updated item lists
 */
public class FlagQueue {
    
    //---------------------------------------------------------------- Constants
    
    //------------------------------------------------------------- Private Data
    /** List of updated items*/
    private static ItemList updatedItemsList = null;
    /** List of deleted items*/
    private static ItemList deletedItemsList = null;
    /** RecordStore created for flags propagation persistence*/
    private static ObjectStore fq = new ObjectStore();
    
    

    private static String FLAGQUEUE = "FlagQueue";

    private static final int UPDATED_LIST_INDEX = 1;
    private static final int DELETED_LIST_INDEX = 2;
    //--------------------------------------------------------------- Properties
    
    //------------------------------------------------------------- Constructors
    /**
     * Creates a new instance of FlagQueue
     * private access: this class just shows static methods
     */
    private FlagQueue() {
        
    }
    
    
    /** initializes private items lists*/
    private static synchronized void init() {
        //Creates the two list of updated and deleted items
        updatedItemsList = new ItemList();
        deletedItemsList = new ItemList();
        
        //saves the two lists in order to persist them into the recordstore
        Log.debug("[FlagQueue.init()] Saving...");
        save();
        Log.debug("[FlagQueue.init()] FQ saved");
        
    }

    private static synchronized void retrievePersistedQueues() {
        
        //Flag queues were persisted on the RMS and are retrieved and associated 
        //To their relaed item lists. If not found the queues are created
        //Useful for the first Sl
        
        if (!isFlagQueuePersisted()) {
            init();
        }
        
        try {
            Log.debug("[FlagQueue.retrievePersistedQueues()] Flag queue found");
            fq.open(FLAGQUEUE);
            updatedItemsList = (FlagQueue.ItemList) fq.retrieve(UPDATED_LIST_INDEX, new ItemList());
            Log.debug("[FlagQueue.retrievePersistedQueues()] Updated List retrieved:");
            Log.debug(updatedItemsList.getList().toString());
            deletedItemsList = (FlagQueue.ItemList) fq.retrieve(DELETED_LIST_INDEX, new ItemList());
            Log.debug("[FlagQueue.retrievePersistedQueues()] Deleted List retrieved");
            Log.debug(deletedItemsList.getList().toString());
            fq.close();
        } catch (IOException ex) {
            Log.error("[FlagQueue.retrievePersistedQueues()] " + ex);
        } catch (RecordStoreException ex) {
            Log.error("[FlagQueue.retrievePersistedQueues()] " + ex);
        }
    }

    /** reset items lists */
    public static synchronized void clear() {
        Log.debug("[FlagQueue.clear()] Clearing flag queues...");
        updatedItemsList = null;
        deletedItemsList = null;
        //delete the FlagQueue recordStore
        try {
            if (isFlagQueuePersisted()) {
                Log.debug("[FlagQueue.clear()] Deleting flag queue store");
                AbstractRecordStore.deleteRecordStore(FLAGQUEUE);
                Log.debug("[FlagQueue.clear()] Flag queue store deleted");
            }
        } catch (RecordStoreException ex) {
            Log.error("[FlagQueue.clear()] Cannot remove flag queue: " + ex);
        } 
    }
    
    private static synchronized boolean isFlagQueuePersisted() {
        String[] rsName = AbstractRecordStore.listRecordStores();
        for (int i=0; i<rsName.length; i++) {
            if (rsName[i].equals(FLAGQUEUE)) {
                return true;
            }
        }
        return false;
    }
    
    
    /**
     * Put a new updated or deleted element on the related list
     * @param key is the key of th item to be delated or replaced on the server
     * @param mf is the MessageFlags related to the give item object
     */
    public static synchronized void put(String key, MessageFlags mf) {
        if (updatedItemsList==null||deletedItemsList==null) {
            Log.debug("[FlagQueue.put()] Flag queue to be initialized");    
            init();
            Log.debug("[FlagQueue.put()] Flag queue Initialized");    
        }
        
        Log.debug("[FlagQueue.put()] Selecting List...");
        selectList(mf).addItem(key, mf);
        
        //if a message has been updated and deleted before the next sync,
        //it is shown on deleted item list only
        if (updatedItemsList.containsItem(key)&&deletedItemsList.containsItem(key)) {
            Log.debug("[FlagQueue.put()] Removing deleted item form updated item list");
            updatedItemsList.removeItem(key);
        }
        
        Log.debug("[FlagQueue.put()] Saving...");
        save();
        Log.debug("[FlagQueue.put()] Saved");
    }
    
    /**
     * Removes an element from the list
     * @param key the key of the item to be removed
     */
    public static synchronized void remove(String key) {
        if (deletedItemsList!=null) {
            if (deletedItemsList.containsItem(key)) {
                Log.debug("[FlagQueue.remove()] Deleting flag from deleted items list");
                deletedItemsList.removeItem(key);
                Log.debug("[FlagQueue.remove()] Removed");
                return;
            }
        }
        if (updatedItemsList!=null) {
            Log.debug("[FlagQueue.remove()] Removing flag from updated item list");
            updatedItemsList.removeItem(key);
            Log.debug("[FlagQueue.remove()] Removed");
        }
        Log.debug("[FlagQueue.remove()] Saving...");
        save();
        Log.debug("[FlagQueue.remove()] Saved");
    }
    
    /**
     * Accesses the item list by item's @param key and gets the related item
     *
     * @param key the key of the message of which the flags are requested
     * @return the flags of the specified key, or null if not found
     */
    public static synchronized MessageFlags get(String key) {
        if (deletedItemsList.containsItem(key)) {
            return (MessageFlags) deletedItemsList.getItem(key);
        } else if (updatedItemsList.containsItem(key)) {
            return (MessageFlags) updatedItemsList.getItem(key);
        }
        return null;
    }
    
    /**
     * @return Hashtable representing the list of updated items
     */
    public static synchronized Hashtable getUpdatedItemsList() {
        Log.debug("[FlagQueue.getUpdatedItemsList()] Retrieving updated item list");
        retrievePersistedQueues();
        return retrieveList(UPDATED_LIST_INDEX);
        //return updatedItemsList==null?new ItemList():updatedItemsList;
    }
    
    /**
     * @return Hashtable representing the list of deleted items
     */
    public static synchronized Hashtable getDeletedItemsList() {
        Log.debug("[FlagQueue.getUpdatedItemsList()] retrieving deleted item list");
        retrievePersistedQueues();
        return retrieveList(DELETED_LIST_INDEX);
        //return deletedItemsList==null?new ItemList():deletedItemsList;
    }
    
   
    private static synchronized Hashtable retrieveList(int index) {
        //first time a sync is performed 
        
        ItemList ret = null; 
        
        try {
            fq.open(FLAGQUEUE);
            
            switch (index) {
                case FlagQueue.UPDATED_LIST_INDEX:
                    Log.debug("[FlagQueue.retrieveList()] retrieving updated item list from store");
                    ret=(FlagQueue.ItemList) fq.retrieve(UPDATED_LIST_INDEX, new ItemList());//updatedItemsList);
                    Log.debug("[FlagQueue.retrieveList()] U list Content:");
                    Log.debug(ret.getList().toString());
                    break;
                case FlagQueue.DELETED_LIST_INDEX:
                    Log.debug("[FlagQueue.retrieveList()] retrieving deleted item list from store");
                    ret=(FlagQueue.ItemList) fq.retrieve(DELETED_LIST_INDEX, new ItemList());//deletedItemsList);
                    Log.debug("[FlagQueue.retrieveList()] D list Content:");
                    Log.debug(ret.getList().toString());
                    break;
                default:
                    Log.debug("[FlagQueue.retrieveList()] Item list is null: ");
                    ret = null;
                    break;
                    
            }
            if (ret.isEmpty()) {
                Log.debug("[FlagQueue.retrieveList()] Item list is empty");
            }
            fq.close();
            
        } catch (IOException ex) {
            Log.error("[FlagQueue.retrieveList()] " + ex);
        } catch (RecordStoreException ex) {
            Log.error("[FlagQueue.retrieveList()] " + ex);
        }
        return ret.getList();
    }
    
    
    /**
     * Select the list to be updated given the @param mf MessaFlags object
     */
    private static synchronized ItemList selectList(MessageFlags mf) {
        if (mf.isSet(MessageFlags.DELETED)) {
            return deletedItemsList;
        }
        return updatedItemsList;
    }
    
    public static synchronized void save() {
        //Creates the recordStore to persist the two list created above
        if (!isFlagQueuePersisted()) {
            //No flag queue has been serialized on the RMS yet
            Log.debug("[FlagQueue.save()] Flag queue is not persisted... Creating");
            try {
                fq.create(FLAGQUEUE);
                Log.debug("[FlagQueue.save()] Flag queue created");
            } catch (RecordStoreException ex) {
                Log.error("[FlagQueue.save()] Cannot persist flag queue: " + ex);
            }
        } 
        try {
            
            if (updatedItemsList==null) {
                Log.debug("[FlagQueue.save()] Updated Item List is null");
                updatedItemsList = new ItemList();
            }

            if (deletedItemsList==null) {
                Log.debug("[FlagQueue.save()] Deleted Item List is null");
                deletedItemsList = new ItemList();
            }

                    
            //serialize delete and updated flags
            //with fq.setRecord method.
            //2 record total
            //FIX HERE!!!!
            Log.debug("[FlagQueue.save()] Flag queue persisted: Updating");
            fq.open(FLAGQUEUE);
                if (fq.size()==0) {
                
                    Log.debug("[FlagQueue.save()] Flag queue size is 0");
            
                    Log.debug("[FlagQueue.save()] Size is 0");
                    int index = fq.store(updatedItemsList);
                    Log.debug("[FlagQueue.save()] Created updated items list at index: " + index);
                    index = fq.store(deletedItemsList);    
                    Log.debug("[FlagQueue.save()] Created deleted items list at index: " + index);
                } else {
                    Log.debug("[FlagQueue.save()] Size is not 0:");
                    Log.debug("[FlagQueue.save()] Updating lists");

                    fq.store(UPDATED_LIST_INDEX, updatedItemsList);
                    fq.store(DELETED_LIST_INDEX, deletedItemsList);    
                }

            Log.debug("[FlagQueue.save()] Closing Store");
                    
            fq.close();
        } catch (RecordStoreException ex) {
            Log.error("[FlagQueue.save()] Cannot serialize flag queue: " + ex);
        } catch (IOException ex) {
            Log.error("[FlagQueue.save()] " + ex);
        }
    }

    static class ItemList extends Hashtable implements Serializable{
        
        private Hashtable itemList = new Hashtable();

        public boolean containsItem(String key) {
            return itemList.containsKey(key);
        }
        
        public void addItem(String key, MessageFlags value) {
            itemList.put(key, value);
        }
        
        public MessageFlags getItem(String key) {
            return (MessageFlags) itemList.get(key);
        }
        
        public void removeItem(String key) {
            itemList.remove(key);
        }
        
        public Hashtable getList() {
            return itemList;
        }
        
        public void setList(Hashtable itemList) {
            this.itemList=itemList;
        }
        
        public void serialize(DataOutputStream out) throws IOException {
            ComplexSerializer.serializeHashTable(out, itemList);
        }

        public void deserialize(DataInputStream in) throws IOException {
            itemList = ComplexSerializer.deserializeHashTable(in);
        }
    }
}

⌨️ 快捷键说明

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