📄 mailsyncsource.java
字号:
Message[] headers = outbox.getMsgHeaders();
int count = headers.length;
if (count > 0) {
newItems = new SyncItem[count];
for(int i=0; i<count; i++) {
String key = makeItemKey(Store.OUTBOX,
headers[i].getMessageId());
newItems[i] =
new SyncItem(key, EMAIL_TYPE,
SyncItem.STATE_NEW, Store.OUTBOX, null);
}
} else {
newItems = null;
}
if (listener != null) {
Log.debug(" init new items start sending call. Count = " + count);
listener.startSending(count);
}
} catch(MailException me) {
Log.error("[MailSyncSource.initNewItems]: " + me.toString());
me.printStackTrace();
throw new SyncException(SyncException.CLIENT_ERROR, me.toString());
}
}
/**
* Not used now. It will be implemented if the Draft folder
* has to be synchronized.
*/
protected void initUpdItems() throws SyncException {
Log.debug("Initializating Updated Items of folder INBOX");
int count = 0;
updItems = null;
Hashtable updatedItemsList = FlagQueue.getUpdatedItemsList();
if (updatedItemsList==null) {
return;
}
count = updatedItemsList.size();
if (count > 0) {
int i=0;
updItems = new SyncItem[count];
Enumeration itemKeys = updatedItemsList.keys();
while (itemKeys.hasMoreElements()) {
String key = (String) itemKeys.nextElement();
updItems[i] =
new SyncItem(key, EMAIL_TYPE,
SyncItem.STATE_UPDATED, folderFromKey(key), null);
i++;
}
}
}
/**
* Init the delItems list used in the fast sync
* TODO: check the state of the message
*/
protected void initDelItems() throws SyncException {
Log.debug("Initializating Deleted Items");
int count=0;
delItems = null;
Hashtable deletedItemsList = FlagQueue.getDeletedItemsList();
if (deletedItemsList==null) {
return;
}
count = deletedItemsList.size();
if (count > 0) {
delItems = new SyncItem[count];
Enumeration itemKeys = deletedItemsList.keys();
int i=0;
while (itemKeys.hasMoreElements()) {
String key = (String) itemKeys.nextElement();
Log.debug("Folder to find: " + folderFromKey(key));
delItems[i] =
new SyncItem(key, EMAIL_TYPE,
SyncItem.STATE_DELETED, folderFromKey(key), null);
i++;
}
}
/*
*we don't need to notify the listener here
if (listener != null) {
listener.startSending(count);
}*/
}
/**
* 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());
try {
EmailData mdata = null;
SyncItem ret = null;
switch(item.getState()){
case SyncItem.STATE_UPDATED:
Folder folder = store.getFolder(item.getParent());
if (folder.getName().equals(Store.INBOX)) {
//Last result to be achieved:
mdata = new EmailData();
mdata.setFlags(FlagQueue.get(item.getKey()));
ret = new SyncItem(item);
ret.setContent(mdata.format());
Log.debug(new String(mdata.format()));
return ret;
}
break;
case SyncItem.STATE_NEW:
if(item.getType().equals(EMAIL_TYPE)) {
// For type email, the content has to be filled,
// for folders, the item is already complete.
// for deleted items
Folder f = store.getFolder(item.getParent());
if (f.getName().equals(Store.OUTBOX)) {
// Remove the folder prefix from the key.
String messageId = msgIdFromKey(item.getKey());
// Get the message
Message msg = f.getMessage(messageId);
mdata = new EmailData(msg);
ret = new SyncItem(item);
ret.setContent(mdata.format());
Log.debug("getItemContent: returning filled item.");
// Return the filled item
return ret;
}
}
break;
default:
break;
}
} catch (MailException me) {
Log.error("[MailSyncSource.getItemContent] Error filling item:"
+ item.getKey());
me.printStackTrace();
throw new SyncException(SyncException.CLIENT_ERROR, me.toString());
}
// If no changes, return the original item
Log.debug("getItemContent: returning original item.");
return item;
}
//-------------------------------------------------------- Private methods
/**
* Add an Email item
*/
private int handleEmailItem(SyncItem item) {
// Get parent folder name (handle 3.0 compatibility)
String parent = folderFromParent(item.getParent());
if(parent == null) {
Log.error("[handleEmailItem]Invalid parent from server: "
+item.getParent());
return 500;
}
// Get only Inbox messages, ignore the others
if(!parent.equals(store.INBOX)) {
Log.debug("[handleEmailItem]Message for "+parent+" discarded");
return 200;
}
EmailData mdata = new EmailData();
try {
mdata.parse(item.getContent());
} catch (XmlException xe) {
Log.error("[handleEmailItem]Error parsing item: " + item.getKey() +
" ("+xe.toString()+")");
xe.printStackTrace();
// Return error to the server
return 500;
} catch (MailException me) {
Log.error("[handleEmailItem]Error parsing message: "+item.getKey() +
" ("+me.toString()+")");
me.printStackTrace();
// Return error to the server
return 500;
} catch (Exception e) {
Log.error("[handleEmailItem]Unexpected exception parsing message: "
+ item.getKey()
+ " ("+e.toString()+")");
e.printStackTrace();
// Return error to the server
return 500;
}
int ret = 500;
switch(item.getState()) {
case SyncItem.STATE_NEW:
String localkey = addMessage(parent, mdata.getEmailItem());
if (localkey != null) {
item.setKey(localkey);
if(listener != null) {
listener.msgReceived(mdata.getEmailItem());
}
ret = 200;
}
break;
case SyncItem.STATE_UPDATED:
ret = updateFlags(parent, item.getKey(), mdata.getFlags());
if(ret == 200 && listener != null) {
listener.msgFlagsUpdated(msgIdFromKey(item.getKey()), mdata.getFlags());
}
break;
default:
Log.error("[handleEmailItem]Unknown state: "+item.getState());
break;
}
return ret;
}
/**
* Add a message.
*/
private String addMessage(String parent, Message msg) {
String localkey = null;
if (msg != null) {
String msgid = msg.getMessageId();
try {
Folder f = store.getFolder(parent);
Log.info("[addMessage]Adding message " + msgid +
" to folder " + f.getName());
f.appendMessage(msg);
// Set item key to LUID
localkey = makeItemKey(f.getName(), msg.getMessageId());
} catch (MailException me) {
Log.error("[addMessage]Error saving message: " + msgid
+ " " + me.toString() );
me.printStackTrace();
// TODO: implement a finer handling of the exception?
mailSourceStatus = AccountListener.STATUS_RECV_ERROR;
}
} else {
// Server can't send flags update only in a Add command.
Log.debug("[addMessage]Invalid empty email data: ");
mailSourceStatus = AccountListener.STATUS_SERVER_ERROR;
}
return localkey;
}
/**
* Update flags.
*/
private int updateFlags(String parent, String key, MessageFlags flags) {
try {
Folder f = store.getFolder(parent);
// Flag update only.
Log.debug("[updateMessage]updating flags for: ", key);
String msgId = msgIdFromKey(key);
Message saved = f.getMessage(msgId);
saved.setFlags(flags);
f.appendMessage(saved);
return 200;
} catch (MailException me) {
Log.error("[addMessage]Error saving message: " + key
+ " " + me.toString() );
me.printStackTrace();
// TODO: implement a finer handling of the exception?
mailSourceStatus = AccountListener.STATUS_RECV_ERROR;
return 500;
}
}
/**
* Add an Folder item
*/
private int addFolderItem(SyncItem item) {
FolderData fdata = new FolderData();
try {
// For the moment, the client don't creates
// other folders on server's request, just checks
// the commands to return the correct status
// and key
fdata.parse(item.getContent());
// Set item key to LUID
item.setKey(fdata.getName());
return 200;
} catch (XmlException xe) {
Log.error("Error parsing item: " + item.getKey());
// Return error to the server
return 500;
}
}
/*
* Convert Funambol 3.0 folder names into local folder names.
*
* @param parent the item parent string
* @return the converted name, or the original one if does not
* starts with "ROOT/"
*
*/
private String folderFromParent(String parent) {
final String root = "ROOT/";
if(parent == null) {
return null;
}
if (parent.startsWith(root)) {
return folderFromPrefix(parent.charAt(root.length()));
}
return parent;
}
/*
* Get the folder name from the key.
*/
private String folderFromKey(String key) {
if(key == null) {
return null;
}
int pos = key.indexOf('/');
if(pos != -1) {
return key.substring(0, pos);
}
return null;
}
/*
* Get the message Id from the key.
*/
private String msgIdFromKey(String key) {
int pos = key.indexOf('/');
if(pos != -1) {
return key.substring(pos+1);
}
return key;
}
/**
* Find the folder name from the Funambol key prefix.
*/
private String folderFromPrefix(char prefix) {
switch (prefix) {
case 'I':
return "Inbox";
case 'O':
return "Outox";
case 'D':
return "Drafts";
case 'S':
return "Sent";
default:
return null;
}
}
/**
* Compose the item key adding the folder prefix to the local key.
* If it's one of the main folders, it is shortened, otherwise
* the whole folder name is used as prefix.
*/
private String makeItemKey(String folder, String key) {
return folder+"/"+key;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -