📄 contactsyncsource.java
字号:
/*
* Copyright (C) 2006-2007 Funambol
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.funambol.mailclient.syncml;
import com.funambol.mailclient.cm.rms.ContactEnumeration;
import com.funambol.mailclient.syncml.PimItem;
import com.funambol.mailclient.cm.Contact;
import com.funambol.mailclient.cm.ContactManager;
import com.funambol.mailclient.cm.ContactManagerFactory;
import com.funambol.mailclient.cm.ContactManagerException;
import com.funambol.mailclient.cm.ContactListFullException;
import com.funambol.mailclient.syncml.PimItemEnumeration;
import com.funambol.storage.ObjectEnumeration;
import com.funambol.storage.ObjectStore;
import com.funambol.mailclient.AccountListener;
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.util.Log;
import com.funambol.util.StringUtil;
import javax.microedition.rms.RecordStoreException;
/**
* An implementation of the <i>SyncSource</i> interface, used to send
* and receive email over the SyncML protocol.
*
*/
public class ContactSyncSource extends BaseSyncSource {
//--------------------------------------------------------------- Attributes
/** Reference to the contact manager */
private ContactManager cm;
/** Flag used to mark the beginning of the receiving phase */
//private boolean receiving;
//------------------------------------------------------------- Constructors
/**
* MailSyncSource constructor: initialize source config and
* init all the rest to null. The real initialization is done by
* the beginSync method.
*/
public ContactSyncSource(SourceConfig config) {
super(config);
try {
cm = ContactManagerFactory.getContactManager(ContactManager.RMS_TYPE);
} catch (RecordStoreException ex) {
ex.printStackTrace();
Log.error(this, "Cannot get RMSContactManager instance");
}
//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()
receiving = false;
}
*/
/*
* 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 cm.
*/
public int addItem(SyncItem item) throws SyncException {
Log.info("New item " + item.getKey() + " from server.");
if(item.getType().equals(SourceConfig.VCARD_TYPE)) {
try {
Contact c = new Contact();
c.parse(new String(item.getContent()));
if ( StringUtil.isNullOrEmpty(c.getDefaultEmail()) ) {
Log.info("no default email, discarding contact: " + c.getVisibleName());
return 500;
}
// Add the new contact
int localkey = cm.addContact(c);
if (localkey != -1) {
String skey = Integer.toString(localkey);
//cm.removeSyncItem(skey);
item.setKey(skey);
return 200;
}
else {
Log.error("addItem: error adding contact");
return 500;
}
} catch (ContactListFullException cfe) {
// Error logged by ContactManager
throw new SyncException(SyncException.LIMIT_ERROR,
"Contact List full");
} catch (Exception ex) {
Log.error("Error parsing contact: " + ex.toString());
return 500;
}
} else {
Log.error("[ContactSyncSource.addItem] Unknown item type: "
+ item.getType());
return 500;
}
}
/** Update a given SyncItem stored on the source backend */
public int updateItem(SyncItem item) {
Log.info("Updated item " + item.getKey() + " from server.");
if(item.getType().equals(SourceConfig.VCARD_TYPE)) {
// Parse the mail item
try {
Contact c = new Contact();
c.parse(new String(item.getContent()));
if (StringUtil.isNullOrEmpty(c.getDefaultEmail()) ) {
Log.info("no default email, discarding contact: " + c.getVisibleName());
return 500;
}
c.setContactId(Integer.parseInt(item.getKey()));
cm.updateContact(c);
cm.removeSyncItem(item.getKey());
return 200;
} catch (ContactManagerException ex) {
Log.error("Cannot update item " + item.getKey());
return 500;
}
} else {
Log.info("[ContactSyncSource.updateItem] Unexpected item type"
+ item.getType());
return 500;
}
}
/** Delete a SyncItem stored on the related Items list */
public int deleteItem(String key) {
Log.info("Delete from server for item " + key);
try {
cm.removeContact(Integer.parseInt(key));
cm.removeSyncItem(key);
return 200;
} catch (ContactManagerException cme) {
Log.error("Error removing contact: " + key + " " + cme.toString());
return 500;
}
}
/**
* 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.");
if (SyncMLStatus.isSuccess(status)) {
//if (this.syncMode!=SyncML.ALERT_CODE_SLOW) {
cm.removeSyncItem(key);
//}
}
}
/**
* Send incomingMsgNumber event when the engine announce the number of
* changes: it is the first Sync tag from server.
*
public void setServerItemsNumber(int number) {
super.setServerItemsNumber(number);
receiving = true;
}
*/
//------------------------------------------------------- Protected methods
/**
* Init the allItems list used in the slow sync with the messages
* in the outbox only.
*/
protected void initAllItems() throws SyncException {
ContactEnumeration list = null;
try {
list = (ContactEnumeration) cm.getContactList();
} catch (ContactManagerException ex) {
Log.error("Error retrieving contatc list");
Log.error("Contact.initAllItems: " + ex.toString());
// TODO: should this throws an exception? I guess so...
}
allItems = new SyncItem[list.getSize()];
for (int i=0; i<list.getSize(); i++) {
if (list.hasMoreElements()) {
Contact c = (Contact) list.nextElement();
allItems[i] = new SyncItem(
String.valueOf(c.getContactId()),
SourceConfig.VCARD_TYPE,
SyncItem.STATE_UPDATED,
null,
null
);
}
}
}
/**
* Init the newItems list used in the fast sync.
*/
protected void initNewItems() throws SyncException {
PimItemEnumeration list =
(PimItemEnumeration) cm.getSyncItems(SyncItem.STATE_NEW);
newItems = new SyncItem[list.getSize()];
for (int i=0; i<list.getSize(); i++) {
if (list.hasMoreElements()) {
PimItem sii = (PimItem) list.nextElement();
newItems[i] = new SyncItem(
sii.getKey(),
SourceConfig.VCARD_TYPE,
SyncItem.STATE_NEW,
null,
null
);
}
}
}
/**
* Init the updItems list used in the fast sync.
*/
protected void initUpdItems() throws SyncException {
PimItemEnumeration list =
(PimItemEnumeration) cm.getSyncItems(SyncItem.STATE_UPDATED);
updItems = new SyncItem[list.getSize()];
for (int i=0; i<list.getSize(); i++) {
if (list.hasMoreElements()) {
PimItem sii = (PimItem) list.nextElement();
updItems[i] = new SyncItem(
sii.getKey(),
SourceConfig.VCARD_TYPE,
SyncItem.STATE_UPDATED,
null,
null
);
}
}
}
/**
* Init the delItems list used in the fast sync
*/
protected void initDelItems() throws SyncException {
PimItemEnumeration list =
(PimItemEnumeration) cm.getSyncItems(SyncItem.STATE_DELETED);
delItems = new SyncItem[list.getSize()];
for (int i=0; i<list.getSize(); i++) {
if (list.hasMoreElements()) {
PimItem sii = (PimItem) list.nextElement();
delItems[i] = new SyncItem(
sii.getKey(),
SourceConfig.VCARD_TYPE,
SyncItem.STATE_DELETED,
null,
null
);
}
}
}
/**
* This function gets the item content in the backend database and
* returns a complete item. The parameter item is marked final because
* should not be used for the filled item: it is a reference to the
* array entry, and filling it would cause the array to keep all the
* filled items at the end (the gc will not dispose them). <p>
* The content of the item depends also from the encoding of this
* SyncSource:
* <li> if the encoding is <i>none</i>, it must be a String, converted
* with getBytes(), so the engine will send it unchanged.
* <li> if the encoding is <i>b64</i>, the content can be binary, and the
* type should be set accordingly, so that the receiving source
* can handle it. In this way, the binary content is transferred
* encoded in the SyncML message. This encoding can be applied to
* a text item too, to avoid problems with charset or other, like
* what is done with the SIF format.
*/
protected SyncItem getItemContent(final SyncItem item) throws SyncException {
Log.debug("Current Item State: " + item.getState());
SyncItem ret = new SyncItem(item);
Contact c = null;
try {
c = cm.getContact(Integer.parseInt(item.getKey()));
ret.setContent(c.format().getBytes());
} catch (NumberFormatException ex) {
Log.error("Error Accessing contact: " + c.getContactId());
Log.error(ex.toString());
ex.printStackTrace();
return item;
} catch (ContactManagerException ex) {
Log.error("Error Accessing contact; " + c.getContactId());
ex.printStackTrace();
return item;
}
return ret;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -