1
0
mirror of https://github.com/moparisthebest/davmail synced 2024-12-13 19:22:22 -05:00

Caldav: additional task fields over EWS and fix urlcompname decoding

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1770 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2011-08-09 13:03:55 +00:00
parent 50d0bc585a
commit 9b6c21de92
4 changed files with 129 additions and 13 deletions

View File

@ -336,8 +336,6 @@ public class Field {
createField("commonstart", DistinguishedPropertySetType.Common, 0x8516, "commonstart", PropertyType.SystemTime);
createField("commonend", DistinguishedPropertySetType.Common, 0x8517, "commonend", PropertyType.SystemTime);
createField("categories", DistinguishedPropertySetType.PublicStrings, 0x9000, "categories", PropertyType.StringArray);
}
protected static String toHexString(int propertyTag) {

View File

@ -34,6 +34,7 @@ import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.util.URIUtil;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
@ -1168,7 +1169,7 @@ public class EwsExchangeSession extends ExchangeSession {
String type;
boolean isException;
protected Event(EWSMethod.Item response) {
protected Event(EWSMethod.Item response) throws URIException {
itemId = new ItemId(response);
type = response.type;
@ -1177,7 +1178,7 @@ public class EwsExchangeSession extends ExchangeSession {
etag = response.get(Field.get("etag").getResponseName());
displayName = response.get(Field.get("displayname").getResponseName());
subject = response.get(Field.get("subject").getResponseName());
itemName = response.get(Field.get("urlcompname").getResponseName());
itemName = StringUtil.decodeUrlcompname(response.get(Field.get("urlcompname").getResponseName()));
// workaround for missing urlcompname in Exchange 2010
if (itemName == null) {
itemName = StringUtil.base64ToUrl(itemId.id) + ".EML";
@ -1252,7 +1253,15 @@ public class EwsExchangeSession extends ExchangeSession {
updates.add(Field.createFieldUpdate("taskstatus", vTodoToTaskStatusMap.get(vTodoStatus)));
}
updates.add(Field.createFieldUpdate("keywords", vCalendar.getFirstVeventPropertyValue("CATEGORIES")));
updates.add(Field.createFieldUpdate("duedate", convertCalendarDateToExchange(vCalendar.getFirstVeventPropertyValue("DUE"))));
updates.add(Field.createFieldUpdate("startdate", convertTaskDateToZulu(vCalendar.getFirstVeventPropertyValue("DTSTART"))));
updates.add(Field.createFieldUpdate("duedate", convertTaskDateToZulu(vCalendar.getFirstVeventPropertyValue("DUE"))));
updates.add(Field.createFieldUpdate("datecompleted", convertTaskDateToZulu(vCalendar.getFirstVeventPropertyValue("COMPLETED"))));
updates.add(Field.createFieldUpdate("commonstart", convertTaskDateToZulu(vCalendar.getFirstVeventPropertyValue("DTSTART"))));
updates.add(Field.createFieldUpdate("commonend", convertTaskDateToZulu(vCalendar.getFirstVeventPropertyValue("DUE"))));
//updates.add(Field.createFieldUpdate("iscomplete", "COMPLETED".equals(vTodoStatus)?"True":"False"));
if (currentItemId != null) {
// update
createOrUpdateItemMethod = new UpdateItemMethod(MessageDisposition.SaveOnly,
@ -1382,8 +1391,11 @@ public class EwsExchangeSession extends ExchangeSession {
getItemMethod.addAdditionalProperty(Field.get("description"));
getItemMethod.addAdditionalProperty(Field.get("percentcomplete"));
getItemMethod.addAdditionalProperty(Field.get("taskstatus"));
getItemMethod.addAdditionalProperty(Field.get("startdate"));
getItemMethod.addAdditionalProperty(Field.get("duedate"));
getItemMethod.addAdditionalProperty(Field.get("keywords"));
getItemMethod.addAdditionalProperty(Field.get("datecompleted"));
getItemMethod.addAdditionalProperty(Field.get("keywords"));
} else if (!"Message".equals(type)) {
getItemMethod = new GetItemMethod(BaseShape.ID_ONLY, itemId, true);
getItemMethod.addAdditionalProperty(Field.get("reminderset"));
@ -1417,11 +1429,13 @@ public class EwsExchangeSession extends ExchangeSession {
vTodo.setPropertyValue("DESCRIPTION", getItemMethod.getResponseItem().get(Field.get("description").getResponseName()));
vTodo.setPropertyValue("PERCENT-COMPLETE", getItemMethod.getResponseItem().get(Field.get("percentcomplete").getResponseName()));
vTodo.setPropertyValue("STATUS", taskTovTodoStatusMap.get(getItemMethod.getResponseItem().get(Field.get("taskstatus").getResponseName())));
vTodo.setPropertyValue("DUE;VALUE=DATE", convertDateFromExchangeToTaskDate(getItemMethod.getResponseItem().get(Field.get("duedate").getResponseName())));
vTodo.setPropertyValue("DTSTART;VALUE=DATE", convertDateFromExchangeToTaskDate(getItemMethod.getResponseItem().get(Field.get("startdate").getResponseName())));
vTodo.setPropertyValue("COMPLETED;VALUE=DATE", convertDateFromExchangeToTaskDate(getItemMethod.getResponseItem().get(Field.get("datecompleted").getResponseName())));
vTodo.setPropertyValue("CATEGORIES", getItemMethod.getResponseItem().get(Field.get("keywords").getResponseName()));
VProperty vProperty = new VProperty("DUE", convertDateFromExchange(getItemMethod.getResponseItem().get(Field.get("duedate").getResponseName())));
vProperty.setParam("TZID", vTimezone.getPropertyValue("TZID"));
vTodo.addProperty(vProperty);
localVCalendar.addVObject(vTodo);
content = localVCalendar.toString().getBytes("UTF-8");
} else {
@ -2072,6 +2086,55 @@ public class EwsExchangeSession extends ExchangeSession {
return zuluDateValue;
}
protected String convertDateFromExchangeToTaskDate(String exchangeDateValue) throws DavMailException {
String zuluDateValue = null;
if (exchangeDateValue != null) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
dateFormat.setTimeZone(GMT_TIMEZONE);
zuluDateValue = dateFormat.format(getExchangeZuluDateFormat().parse(exchangeDateValue));
} catch (ParseException e) {
throw new DavMailException("EXCEPTION_INVALID_DATE", exchangeDateValue);
}
}
return zuluDateValue;
}
protected String convertTaskDateToZulu(String value) {
String result = null;
if (value != null && value.length() > 0) {
try {
SimpleDateFormat parser;
if (value.length() == 8) {
parser = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
parser.setTimeZone(GMT_TIMEZONE);
} else if (value.length() == 15) {
parser = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
parser.setTimeZone(GMT_TIMEZONE);
} else if (value.length() == 16) {
parser = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.ENGLISH);
parser.setTimeZone(GMT_TIMEZONE);
} else {
parser = ExchangeSession.getExchangeZuluDateFormat();
}
Calendar calendarValue = Calendar.getInstance(GMT_TIMEZONE);
calendarValue.setTime(parser.parse(value));
// zulu time: add 12 hours
if (value.length() == 16) {
calendarValue.add(Calendar.HOUR, 12);
}
calendarValue.set(Calendar.HOUR, 0);
calendarValue.set(Calendar.MINUTE, 0);
calendarValue.set(Calendar.SECOND, 0);
result = ExchangeSession.getExchangeZuluDateFormat().format(calendarValue.getTime());
} catch (ParseException e) {
LOGGER.warn("Invalid date: " + value);
}
}
return result;
}
/**
* Format date to exchange search format.
*

View File

@ -18,6 +18,8 @@
*/
package davmail.exchange.ews;
import davmail.exchange.dav.PropertyType;
import java.util.HashMap;
import java.util.Map;
@ -56,7 +58,7 @@ public final class Field {
FIELD_MAP.put("mimeContent", new UnindexedFieldURI("item:MimeContent"));
// use PR_RECORD_KEY as unique key
// use PR_RECORD_KEY as unique key
FIELD_MAP.put("uid", new ExtendedFieldURI(0x0FF9, ExtendedFieldURI.PropertyType.Binary));
FIELD_MAP.put("messageFlags", new ExtendedFieldURI(0x0e07, ExtendedFieldURI.PropertyType.Integer));//PR_MESSAGE_FLAGS
FIELD_MAP.put("imapUid", new ExtendedFieldURI(0x0e23, ExtendedFieldURI.PropertyType.Integer));
@ -210,7 +212,14 @@ public final class Field {
// task
FIELD_MAP.put("percentcomplete", new UnindexedFieldURI("task:PercentComplete"));
FIELD_MAP.put("taskstatus", new UnindexedFieldURI("task:Status"));
FIELD_MAP.put("duedate", new UnindexedFieldURI("task:DueDate"));
FIELD_MAP.put("startdate", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Task, 0x8104, ExtendedFieldURI.PropertyType.SystemTime));
FIELD_MAP.put("duedate", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Task, 0x8105, ExtendedFieldURI.PropertyType.SystemTime));
FIELD_MAP.put("datecompleted", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Task, 0x810F, ExtendedFieldURI.PropertyType.SystemTime));
FIELD_MAP.put("iscomplete", new UnindexedFieldURI("task:IsComplete"));
FIELD_MAP.put("commonstart", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Task, 0x8516, ExtendedFieldURI.PropertyType.SystemTime));
FIELD_MAP.put("commonend", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.Task, 0x8517, ExtendedFieldURI.PropertyType.SystemTime));
// attachments
FIELD_MAP.put("attachments", new UnindexedFieldURI("item:Attachments"));

View File

@ -137,7 +137,15 @@ public final class StringUtil {
private static final Pattern CR_PATTERN = Pattern.compile("\r");
private static final Pattern LF_PATTERN = Pattern.compile("\n");
private static final Pattern URLENCODED_F8FF_PATTERN = Pattern.compile(String.valueOf((char) 0xF8FF));
private static final Pattern URLENCODED_AMP_PATTERN = Pattern.compile("%26");
private static final Pattern URLENCODED_PLUS_PATTERN = Pattern.compile("%2B");
private static final Pattern URLENCODED_COLON_PATTERN = Pattern.compile("%3A");
private static final Pattern URLENCODED_LT_PATTERN = Pattern.compile("%3C");
private static final Pattern URLENCODED_GT_PATTERN = Pattern.compile("%3E");
private static final Pattern URLENCODED_QUOTE_PATTERN = Pattern.compile("%22");
private static final Pattern URLENCODED_X0D0A_PATTERN = Pattern.compile("\r\n");
private static final Pattern URLENCODED_PERCENT_PATTERN = Pattern.compile("%25");
private static final Pattern ENCODED_AMP_PATTERN = Pattern.compile("&");
private static final Pattern ENCODED_LT_PATTERN = Pattern.compile("<");
@ -284,6 +292,9 @@ public final class StringUtil {
*/
public static String encodeUrlcompname(String value) {
String result = value;
if (result.indexOf('%') >= 0) {
result = PERCENT_PATTERN.matcher(result).replaceAll("%25");
}
if (result.indexOf("_xF8FF_") >= 0) {
result = F8FF_PATTERN.matcher(result).replaceAll(String.valueOf((char) 0xF8FF));
}
@ -308,8 +319,43 @@ public final class StringUtil {
if (result.indexOf("_x000D__x000A_") >= 0) {
result = X0D0A_PATTERN.matcher(result).replaceAll("\r\n");
}
if (result.indexOf('%') >= 0) {
result = PERCENT_PATTERN.matcher(result).replaceAll("%25");
return result;
}
/**
* Decode urlcompname to get item name.
*
* @param urlcompname encoded value
* @return decoded value
*/
public static String decodeUrlcompname(String urlcompname) {
String result = urlcompname;
if (result.indexOf((char) 0xF8FF) >= 0) {
result = URLENCODED_F8FF_PATTERN.matcher(result).replaceAll("_xF8FF_");
}
if (result.indexOf("%26") >= 0) {
result = URLENCODED_AMP_PATTERN.matcher(result).replaceAll("&");
}
if (result.indexOf("%2B") >= 0) {
result = URLENCODED_PLUS_PATTERN.matcher(result).replaceAll("+");
}
if (result.indexOf("%3A") >= 0) {
result = URLENCODED_COLON_PATTERN.matcher(result).replaceAll(":");
}
if (result.indexOf("%3C") >= 0) {
result = URLENCODED_LT_PATTERN.matcher(result).replaceAll("<");
}
if (result.indexOf("%3E") >= 0) {
result = URLENCODED_GT_PATTERN.matcher(result).replaceAll(">");
}
if (result.indexOf("%22") >= 0) {
result = URLENCODED_QUOTE_PATTERN.matcher(result).replaceAll("\"");
}
if (result.indexOf("\r\n") >= 0) {
result = URLENCODED_X0D0A_PATTERN.matcher(result).replaceAll("_x000D__x000A_");
}
if (result.indexOf("%25") >= 0) {
result = URLENCODED_PERCENT_PATTERN.matcher(result).replaceAll("%");
}
return result;
}