mirror of
https://github.com/moparisthebest/davmail
synced 2025-02-28 09:21:49 -05:00
Caldav: Implement FBTYPE support on Freebusy requests
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@469 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
aa9e56de99
commit
c5985ff9f8
@ -596,9 +596,9 @@ public class CaldavConnection extends AbstractConnection {
|
||||
}
|
||||
}
|
||||
// get freebusy for each attendee
|
||||
HashMap<String, String> freeBusyMap = new HashMap<String, String>();
|
||||
HashMap<String, ExchangeSession.FreeBusy> freeBusyMap = new HashMap<String, ExchangeSession.FreeBusy>();
|
||||
for (String attendee : attendees) {
|
||||
String freeBusy = session.getFreebusy(attendee, valueMap);
|
||||
ExchangeSession.FreeBusy freeBusy = session.getFreebusy(attendee, valueMap);
|
||||
if (freeBusy != null) {
|
||||
freeBusyMap.put(attendee, freeBusy);
|
||||
}
|
||||
@ -607,14 +607,14 @@ public class CaldavConnection extends AbstractConnection {
|
||||
CaldavResponse response = new CaldavResponse(HttpStatus.SC_OK);
|
||||
response.startScheduleResponse();
|
||||
|
||||
for (Map.Entry<String, String> entry : freeBusyMap.entrySet()) {
|
||||
for (Map.Entry<String, ExchangeSession.FreeBusy> entry : freeBusyMap.entrySet()) {
|
||||
String attendee = entry.getKey();
|
||||
response.startRecipientResponse(attendee);
|
||||
|
||||
StringBuilder ics = new StringBuilder();
|
||||
ics.append("BEGIN:VCALENDAR").append((char) 13).append((char) 10)
|
||||
.append("VERSION:2.0").append((char) 13).append((char) 10)
|
||||
.append("PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN").append((char) 13).append((char) 10)
|
||||
.append("PRODID:-//davmail.sf.net/NONSGML DavMail Calendar V1.1//EN").append((char) 13).append((char) 10)
|
||||
.append("METHOD:REPLY").append((char) 13).append((char) 10)
|
||||
.append("BEGIN:VFREEBUSY").append((char) 13).append((char) 10)
|
||||
.append("DTSTAMP:").append(valueMap.get("DTSTAMP")).append("").append((char) 13).append((char) 10)
|
||||
@ -623,9 +623,7 @@ public class CaldavConnection extends AbstractConnection {
|
||||
.append("DTEND:").append(valueMap.get("DTEND")).append("").append((char) 13).append((char) 10)
|
||||
.append("UID:").append(valueMap.get("UID")).append("").append((char) 13).append((char) 10)
|
||||
.append(attendeeKeyMap.get(attendee)).append(":").append(attendee).append("").append((char) 13).append((char) 10);
|
||||
if (entry.getValue().length() > 0) {
|
||||
ics.append("FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:").append(entry.getValue()).append("").append((char) 13).append((char) 10);
|
||||
}
|
||||
entry.getValue().appendTo(ics);
|
||||
ics.append("END:VFREEBUSY").append((char) 13).append((char) 10)
|
||||
.append("END:VCALENDAR");
|
||||
response.appendCalendarData(ics.toString());
|
||||
|
@ -38,6 +38,8 @@ public class ExchangeSession {
|
||||
|
||||
public static final SimpleTimeZone GMT_TIMEZONE = new SimpleTimeZone(0, "GMT");
|
||||
|
||||
protected static final int FREE_BUSY_INTERVAL = 15;
|
||||
|
||||
protected static final Vector<String> EVENT_REQUEST_PROPERTIES = new Vector<String>();
|
||||
|
||||
static {
|
||||
@ -609,7 +611,7 @@ public class ExchangeSession {
|
||||
String folderUrl = getFolderPath(folderName);
|
||||
MessageList messages = new MessageList();
|
||||
String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
|
||||
" ,\"http://schemas.microsoft.com/mapi/proptag/x0e230003\""+
|
||||
" ,\"http://schemas.microsoft.com/mapi/proptag/x0e230003\"" +
|
||||
" ,\"http://schemas.microsoft.com/mapi/proptag/x10830003\", \"http://schemas.microsoft.com/mapi/proptag/x10900003\"" +
|
||||
" ,\"http://schemas.microsoft.com/mapi/proptag/x0E070003\", \"http://schemas.microsoft.com/mapi/proptag/x10810003\"" +
|
||||
" ,\"urn:schemas:mailheader:message-id\", \"urn:schemas:httpmail:read\", \"DAV:isdeleted\", \"urn:schemas:mailheader:date\"" +
|
||||
@ -1822,15 +1824,13 @@ public class ExchangeSession {
|
||||
}
|
||||
}
|
||||
|
||||
public String getFreebusy(String attendee, Map<String, String> valueMap) throws IOException {
|
||||
String result = null;
|
||||
public FreeBusy getFreebusy(String attendee, Map<String, String> valueMap) throws IOException {
|
||||
|
||||
String startDateValue = valueMap.get("DTSTART");
|
||||
String endDateValue = valueMap.get("DTEND");
|
||||
if (attendee.startsWith("mailto:")) {
|
||||
attendee = attendee.substring("mailto:".length());
|
||||
}
|
||||
int interval = 15;
|
||||
|
||||
SimpleDateFormat icalParser = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
|
||||
icalParser.setTimeZone(GMT_TIMEZONE);
|
||||
@ -1858,12 +1858,13 @@ public class ExchangeSession {
|
||||
url = "/public/?cmd=freebusy" +
|
||||
"&start=" + owaFormatter.format(startDate) +
|
||||
"&end=" + owaFormatter.format(endDate) +
|
||||
"&interval=" + interval +
|
||||
"&interval=" + FREE_BUSY_INTERVAL +
|
||||
"&u=SMTP:" + attendee;
|
||||
} catch (ParseException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
|
||||
FreeBusy freeBusy = null;
|
||||
GetMethod getMethod = new GetMethod(url);
|
||||
getMethod.setRequestHeader("Content-Type", "text/xml");
|
||||
|
||||
@ -1877,45 +1878,87 @@ public class ExchangeSession {
|
||||
int endIndex = body.lastIndexOf("</a:fbdata>");
|
||||
if (startIndex >= 0 && endIndex >= 0) {
|
||||
String fbdata = body.substring(startIndex + "<a:fbdata>".length(), endIndex);
|
||||
if (fbdata.length() > 0) {
|
||||
Calendar currentCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
currentCal.setTime(startDate);
|
||||
|
||||
StringBuilder busyBuffer = new StringBuilder();
|
||||
boolean isBusy = fbdata.charAt(0) != '0' && fbdata.charAt(0) != '4';
|
||||
if (isBusy) {
|
||||
busyBuffer.append(icalParser.format(currentCal.getTime()));
|
||||
}
|
||||
boolean knownAttendee = fbdata.charAt(0) != '4';
|
||||
for (int i = 1; i < fbdata.length(); i++) {
|
||||
knownAttendee = knownAttendee || fbdata.charAt(i) != '4';
|
||||
currentCal.add(Calendar.MINUTE, interval);
|
||||
if (isBusy && fbdata.charAt(i) == '0') {
|
||||
// busy -> non busy
|
||||
busyBuffer.append('/').append(icalParser.format(currentCal.getTime()));
|
||||
} else if (!isBusy && (fbdata.charAt(i) != '0') && fbdata.charAt(0) != '4') {
|
||||
// non busy -> busy
|
||||
if (busyBuffer.length() > 0) {
|
||||
busyBuffer.append(',');
|
||||
}
|
||||
busyBuffer.append(icalParser.format(currentCal.getTime()));
|
||||
}
|
||||
isBusy = fbdata.charAt(i) != '0' && fbdata.charAt(0) != '4';
|
||||
}
|
||||
// still busy at end
|
||||
if (isBusy) {
|
||||
busyBuffer.append('/').append(icalParser.format(currentCal.getTime()));
|
||||
}
|
||||
if (knownAttendee) {
|
||||
result = busyBuffer.toString();
|
||||
}
|
||||
}
|
||||
freeBusy = new FreeBusy(icalParser, startDate, fbdata);
|
||||
}
|
||||
} finally {
|
||||
getMethod.releaseConnection();
|
||||
}
|
||||
|
||||
return result;
|
||||
return freeBusy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange to iCalendar Free/Busy parser.
|
||||
* Free time returns 0, Tentative returns 1, Busy returns 2, and Out of Office (OOF) returns 3
|
||||
*/
|
||||
public static final class FreeBusy {
|
||||
SimpleDateFormat icalParser;
|
||||
boolean knownAttendee = true;
|
||||
static final HashMap<Character, String> FBTYPES = new HashMap<Character, String>();
|
||||
|
||||
static {
|
||||
FBTYPES.put('1', "BUSY-TENTATIVE");
|
||||
FBTYPES.put('2', "BUSY");
|
||||
FBTYPES.put('3', "BUSY-UNAVAILABLE");
|
||||
}
|
||||
|
||||
HashMap<String, StringBuilder> busyMap = new HashMap<String, StringBuilder>();
|
||||
|
||||
protected StringBuilder getBusyBuffer(char type) {
|
||||
String fbType = FBTYPES.get(Character.valueOf(type));
|
||||
StringBuilder buffer = busyMap.get(fbType);
|
||||
if (buffer == null) {
|
||||
buffer = new StringBuilder();
|
||||
busyMap.put(fbType, buffer);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected void startBusy(char type, Calendar currentCal) {
|
||||
if (type == '4') {
|
||||
knownAttendee = false;
|
||||
} else if (type != '0') {
|
||||
StringBuilder busyBuffer = getBusyBuffer(type);
|
||||
if (busyBuffer.length() > 0) {
|
||||
busyBuffer.append(',');
|
||||
}
|
||||
busyBuffer.append(icalParser.format(currentCal.getTime()));
|
||||
}
|
||||
}
|
||||
|
||||
protected void endBusy(char type, Calendar currentCal) {
|
||||
if (type != '0' && type != '4') {
|
||||
getBusyBuffer(type).append('/').append(icalParser.format(currentCal.getTime()));
|
||||
}
|
||||
}
|
||||
|
||||
public FreeBusy(SimpleDateFormat icalParser, Date startDate, String fbdata) {
|
||||
this.icalParser = icalParser;
|
||||
if (fbdata.length() > 0) {
|
||||
Calendar currentCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||
currentCal.setTime(startDate);
|
||||
|
||||
startBusy(fbdata.charAt(0), currentCal);
|
||||
for (int i = 1; i < fbdata.length() && knownAttendee; i++) {
|
||||
currentCal.add(Calendar.MINUTE, FREE_BUSY_INTERVAL);
|
||||
char previousState = fbdata.charAt(i - 1);
|
||||
char currentState = fbdata.charAt(i);
|
||||
if (previousState != currentState) {
|
||||
endBusy(previousState, currentCal);
|
||||
startBusy(currentState, currentCal);
|
||||
}
|
||||
}
|
||||
currentCal.add(Calendar.MINUTE, FREE_BUSY_INTERVAL);
|
||||
endBusy(fbdata.charAt(fbdata.length() - 1), currentCal);
|
||||
}
|
||||
}
|
||||
|
||||
public void appendTo(StringBuilder buffer) {
|
||||
for (Map.Entry<String, StringBuilder> entry : busyMap.entrySet()) {
|
||||
buffer.append("FREEBUSY;FBTYPE=").append(entry.getKey())
|
||||
.append(":").append(entry.getValue()).append((char) 13).append((char) 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user