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:
parent
50d0bc585a
commit
9b6c21de92
@ -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) {
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user