package com.fsck.k9.mail.store.webdav;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import timber.log.Timber;
/**
* Maintains WebDAV data
*/
class DataSet {
private Map<String, Map<String, String>> mData = new HashMap<String, Map<String, String>>();
private StringBuilder mUid = new StringBuilder();
private Map<String, String> mTempData = new HashMap<String, String>();
public void addValue(String value, String tagName) {
if (tagName.equals("uid")) {
mUid.append(value);
}
if (mTempData.containsKey(tagName)) {
mTempData.put(tagName, mTempData.get(tagName) + value);
} else {
mTempData.put(tagName, value);
}
}
public void finish() {
String uid = mUid.toString();
if (mTempData != null) {
mData.put(uid, mTempData);
} else if (mTempData != null) {
//TODO: This logic is clearly wrong
/*
* Lost Data are for requests that don't include a message UID. These requests should only have a depth
* of one for the response so it will never get stomped over.
*/
}
mUid = new StringBuilder();
mTempData = new HashMap<String, String>();
}
/**
* Returns a hashmap of special folder name => special folder url
*/
public Map<String, String> getSpecialFolderToUrl() {
// We return the first (and only) map
for (Map<String, String> folderMap : mData.values()) {
return folderMap;
}
return new HashMap<String, String>();
}
/**
* Returns a hashmap of Message UID => Message Url
*/
public Map<String, String> getUidToUrl() {
Map<String, String> uidToUrl = new HashMap<String, String>();
for (String uid : mData.keySet()) {
Map<String, String> data = mData.get(uid);
String value = data.get("href");
if (value != null &&
!value.equals("")) {
uidToUrl.put(uid, value);
}
}
return uidToUrl;
}
/**
* Returns a hashmap of Message UID => Read Status
*/
public Map<String, Boolean> getUidToRead() {
Map<String, Boolean> uidToRead = new HashMap<String, Boolean>();
for (String uid : mData.keySet()) {
Map<String, String> data = mData.get(uid);
String readStatus = data.get("read");
if (readStatus != null && !readStatus.equals("")) {
Boolean value = !readStatus.equals("0");
uidToRead.put(uid, value);
} else {
// We don't actually want to have null values in our hashmap,
// as it causes the calling code to crash with an NPE as it
// does a lookup in the map.
uidToRead.put(uid, false);
}
}
return uidToRead;
}
/**
* Returns an array of all hrefs (urls) that were received
*/
public String[] getHrefs() {
List<String> hrefs = new ArrayList<String>();
for (String uid : mData.keySet()) {
Map<String, String> data = mData.get(uid);
String href = data.get("href");
hrefs.add(href);
}
return hrefs.toArray(WebDavConstants.EMPTY_STRING_ARRAY);
}
/**
* Return an array of all Message UIDs that were received
*/
public String[] getUids() {
List<String> uids = new ArrayList<String>();
for (String uid : mData.keySet()) {
uids.add(uid);
}
return uids.toArray(WebDavConstants.EMPTY_STRING_ARRAY);
}
/**
* Returns the message count as it was retrieved
*/
public int getMessageCount() {
// It appears that Exchange is returning responses
// without a visiblecount element for empty folders
// Which resulted in this code returning -1 (as that was
// the previous default.)
// -1 is an error condition. Now the default is empty
int messageCount = 0;
for (String uid : mData.keySet()) {
Map<String, String> data = mData.get(uid);
String count = data.get("visiblecount");
if (count != null &&
!count.equals("")) {
messageCount = Integer.parseInt(count);
}
}
return messageCount;
}
/**
* Returns a Map of message UID => ParsedMessageEnvelope
*/
public Map<String, ParsedMessageEnvelope> getMessageEnvelopes() {
Map<String, ParsedMessageEnvelope> envelopes = new HashMap<String, ParsedMessageEnvelope>();
for (String uid : mData.keySet()) {
ParsedMessageEnvelope envelope = new ParsedMessageEnvelope();
Map<String, String> data = mData.get(uid);
if (data != null) {
for (Map.Entry<String, String> entry : data.entrySet()) {
String header = entry.getKey();
if (header.equals("read")) {
String read = entry.getValue();
boolean readStatus = !read.equals("0");
envelope.setReadStatus(readStatus);
} else if (header.equals("date")) {
/**
* Exchange doesn't give us rfc822 dates like it claims. The date is in the format:
* yyyy-MM-dd'T'HH:mm:ss.SSS<Single digit representation of timezone, so far, all instances
* are Z>
*/
String date = entry.getValue();
date = date.substring(0, date.length() - 1);
DateFormat dfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
DateFormat dfOutput = new SimpleDateFormat("EEE, d MMM yy HH:mm:ss Z", Locale.US);
String tempDate = "";
try {
Date parsedDate = dfInput.parse(date);
tempDate = dfOutput.format(parsedDate);
} catch (java.text.ParseException pe) {
Timber.e(pe, "Error parsing date: %s", date);
}
envelope.addHeader(header, tempDate);
} else {
envelope.addHeader(header, entry.getValue());
}
}
}
envelopes.put(uid, envelope);
}
return envelopes;
}
}