📄 rmscontactmanager.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.cm.rms;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordStoreException;
import com.funambol.mailclient.cm.Contact;
import com.funambol.mailclient.cm.ContactListFullException;
import com.funambol.mailclient.cm.ContactManager;
import com.funambol.mailclient.cm.ContactManagerEvent;
import com.funambol.mailclient.cm.ContactManagerException;
import com.funambol.mailclient.cm.ContactManagerListener;
import com.funambol.mailclient.config.ConfigManager;
import com.funambol.mailclient.syncml.PimItem;
import com.funambol.mailclient.syncml.PimItemEnumeration;
import com.funambol.mailclient.syncml.PimItemQueue;
import com.funambol.storage.AbstractRecordStore;
import com.funambol.storage.ObjectComparator;
import com.funambol.storage.ObjectEnumeration;
import com.funambol.storage.ObjectStore;
import com.funambol.syncml.spds.SyncItem;
import com.funambol.util.Log;
import com.funambol.util.StringUtil;
/**
* Contact Manager with RMS support and cache
*/
public class RMSContactManager implements ContactManager{
public static final String CONTACT_STORE = "ContactStore";
public static String SYNC_ITEM_STORE = "SyncItemStore";
private static long MIN_STORE_SIZE = 512*1024;
private PimItemQueue syncItemList = null;
private ObjectStore contactStore = null;
private String storeName = null;
private Contact existentContact = null;
private int defaultContactNumber = Integer.MAX_VALUE;
// true if the cache has been loaded
private boolean cacheLoaded = false;
private Vector contactsVector;
/**
* the contactManagerListener object that will be notified of the events
*/
private ContactManagerListener listener=null;
// the default alphabetical comparator
private ContactComparator comparator;
/**
* Creates a new instance of RMSContactManager
*/
public RMSContactManager(String contactStoreName) {
storeName = contactStoreName;
try {
contactStore = new ObjectStore();
contactStore.create(storeName);
syncItemList = new PimItemQueue();
if (ConfigManager.getConfig().getRmsStoreSize()<=MIN_STORE_SIZE) {
setDefaultContactNumber(CONTACT_LIST_MAX_SIZE);
} else {
setDefaultContactNumber(CONTACT_LIST_MAX_SIZE*10);
}
//This avoid DUPLICATED CONTACTS:
Log.debug("[CM] Constructor: Initializing cache");
initCache();
Log.debug("[CM] Constructor: Initializing Comparator");
comparator = new ContactComparator();
contactStore.setObjectComparator(comparator);
Log.debug("Number of contact to be stored: " +defaultContactNumber);
Log.debug("Maximum Space available on device's RMS: "
+ ConfigManager.getConfig().getRmsStoreSize());
Log.debug("Maximum Space Expected: " + MIN_STORE_SIZE);
} catch (RecordStoreException ex) {
Log.error("[ContactManager - Default Constructor]" + ex.toString());
} catch (Exception e) {
Log.error("[ContactManager - Default Constructor]" + e.toString());
}
}
/**
* load the contacts into the cache, after the first call
* the method does nothing.
*/
private synchronized void initCache() {
Log.debug(this, "InitCache");
if (!cacheLoaded) {
Log.debug(this, "Loading Cache from rms");
// using this number to avoid resize of the vectors.
int count = getDefaultContactNumber() +1;
contactStore.removeObjectFilter();
contactStore.removeObjectComparator();
Enumeration e = contactStore.getObjects(new SerializableContact());
ContactEnumeration ce = new ContactEnumeration((ObjectEnumeration) e);
// init contactVectors with correct size to avoid resize
if (ce==null) {
cacheLoaded=false;
Log.error("[CM.initCache()] Cannot retrieve objects");
contactsVector = new Vector(count);
return;
}
contactsVector = new Vector(count);
while (ce.hasMoreElements()) {
//contactsVector.addElement(ce.nextElement());
Contact c = (Contact)ce.nextElement();
//add listener Commands here
if (c!=null) {
contactsVector.addElement(c);
}
}
bubbleSortElements(contactsVector);
cacheLoaded = true;
}
Log.debug(this, "End Initcache, contactsvector size = " + contactsVector.size());
}
public void bubbleSortElements(Vector elements) {
long start = System.currentTimeMillis();
int n = elements.size();
for (int pass = 1; pass < n; pass++) { // count how many times
// This next loop becomes shorter and shorter
for (int i = 0; i < n-pass; i++) {
Contact c1 = (Contact)elements.elementAt(i);
Contact c2 = (Contact)elements.elementAt(i+1);
String vn1 = c1.getVisibleName();
String vn2 = c2.getVisibleName();
if (vn1.toLowerCase().compareTo(vn2.toLowerCase()) > 0) {
// exchange elements
Object temp = elements.elementAt(i);
elements.setElementAt(elements.elementAt(i+1),i);
elements.setElementAt(temp, i+1);
}
}
}
long end = System.currentTimeMillis()-start;
Log.debug("Sorting time: " + end);
}
/**
* Retrieve a contact from the contact store
* @param contactId is the contactId of the stored contact
*
* @return Contact Object retrieved at the give index
*/
public Contact getContact(int contactId) throws ContactManagerException {
Log.debug(this, "getContact!");
Enumeration e = getContactsVector().elements();
Contact c = new Contact();
while ( e.hasMoreElements() ) {
c = (Contact) e.nextElement();
if ( c.getContactId() == contactId ){
Log.debug(this, "contact found");
return c;
}
}
throw new ContactManagerException("Contact not found");
}
/**
* Removes one contact from the contact store
* @param contactId contact id of the contact to be removed
* @throw ContactManagerException when the contact cannot be retrieved
*/
public void removeContact(int contactId) throws ContactManagerException{
try {
contactStore.remove(contactId);
for (int i = 0; i<getContactsVector().size(); i++) {
Contact contact = (Contact) getContactsVector().elementAt(i);
if ( (contact).getContactId() ==
contactId ) {
getContactsVector().removeElementAt(i);
if(listener != null) {
Log.debug("Sending update event (delete)");
ContactManagerEvent event = new ContactManagerEvent(
ContactManagerEvent.EVENT_CODE_DELETE_CONTACT, contact);
listener.update(event);
}
break;
}
}
//SerializableContact sc = (SerializableContact) getContact(index);
addSyncItem(String.valueOf(contactId), SyncItem.STATE_DELETED);
} catch (RecordStoreException ex) {
Log.error(this, "removeContact , recordstore exception removing " +
"contact with index" + contactId);
ex.printStackTrace();
throw new ContactManagerException("Contact manager error: " +
"unable to remove contact at index " + contactId);
}
}
/**
* Gets full Contact Store contacts
* @return Enumeration of contacts objects
*/
public Enumeration getContactList() {
Log.debug(this, "getcontactList() returning contactsvector");
return getContactsVector().elements();
}
/**
* Update contact information on the recordstore
* @param contact to be updated
* @throws ContactManagerException
*/
public void updateContact(Contact contact) throws ContactManagerException {
SerializableContact sc = new SerializableContact(
//contact.getContactId());
contact.getNickName(),
contact.getFirstName(),
contact.getLastName(),
contact.getDefaultEmail(),
contact.getEmail_2(),
contact.getEmail_3(),
contact.getHomePhone(),
contact.getJobPhone(),
contact.getMobilePhone());
try {
sc.setContactId(contact.getContactId());
contactStore.store(contact.getContactId(), sc);
Contact current;
for (int i = 0; i<getContactsVector().size(); i++) {
current = (Contact) getContactsVector().elementAt(i);
if ( current.getContactId() == contact.getContactId() ) {
if (current.getVisibleName().equals(contact.getVisibleName())) {
// if visible name has not been changed contact is
// cached in the right position, we can change it
getContactsVector().setElementAt(contact, i);
} else {
// we need to move it to the right position
getContactsVector().removeElementAt(i);
getContactsVector().insertElementAt(contact, getPosition(contact));
}
}
}
addSyncItem(String.valueOf(contact.getContactId()),SyncItem.STATE_UPDATED);
} catch (RecordStoreException ex) {
ex.printStackTrace();
Log.error(this, "updateContact() recordstore exception while " +
"updating contact " + contact.getVisibleName() + ", throwing" +
" ContactManagerException");
throw new ContactManagerException("Contact manager error: " +
" unable to update contact");
} catch (IOException ex) {
Log.error(this, "IOException while " +
"updating contact " + contact.getVisibleName());
ex.printStackTrace();
}
if(listener != null) {
Log.debug("Sending update event (update)");
ContactManagerEvent event = new ContactManagerEvent(
ContactManagerEvent.EVENT_CODE_UPDATE_CONTACT, contact);
listener.update(event);
}
}
/**
* Store a new record in the Recordstore <br/>
* NO LOG IS ADDED TO THE JOURNAL
*
*
* @param contact the object of type Contact that will be saved
* @returns the id of the new record
*/
public int addContact(Contact contact) throws ContactManagerException {
return addContact(contact, false);
}
/**
* Store a new record in the Recordstore
* @param contact the object of type Contact that will be saved
* @param addToJournal if true register the add to the journal of events
* @returns the id of the new record
*/
public int addContact(Contact contact, boolean addToJournal)
throws ContactManagerException {
if (contactStore.size() >= defaultContactNumber) {
Log.error("Contact List is full. ContactStore size: " +
contactStore.size() + " - defaultContactNumber: " + defaultContactNumber);
throw new ContactListFullException("Contact List Full");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -