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

Caldav: improve filter handling, support VTODO/VEVENT comp-filter

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1394 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2010-08-29 16:15:28 +00:00
parent 98ae8917c0
commit f6a6dd9333
3 changed files with 133 additions and 32 deletions

View File

@ -704,7 +704,13 @@ public class CaldavConnection extends AbstractConnection {
appendEventsResponses(response, request, events);
} else {
// TODO: handle contacts ?
events = session.searchEvents(request.getFolderPath(), request.timeRangeStart, request.timeRangeEnd);
if (request.vTodoOnly) {
events = session.searchTasksOnly(request.getFolderPath());
} else if (request.vEventOnly) {
events = session.searchEventsOnly(request.getFolderPath(), request.timeRangeStart, request.timeRangeEnd);
} else {
events = session.searchEvents(request.getFolderPath(), request.timeRangeStart, request.timeRangeEnd);
}
appendEventsResponses(response, request, events);
}
@ -1209,6 +1215,8 @@ public class CaldavConnection extends AbstractConnection {
protected boolean isMultiGet;
protected String timeRangeStart;
protected String timeRangeEnd;
protected boolean vTodoOnly;
protected boolean vEventOnly;
protected CaldavRequest(String command, String path, Map<String, String> headers, String body) throws IOException {
this.command = command;
@ -1418,7 +1426,14 @@ public class CaldavConnection extends AbstractConnection {
public void handleCompFilter(XMLStreamReader reader) throws XMLStreamException {
while (reader.hasNext() && !isEndTag(reader, "comp-filter")) {
reader.nextTag();
if (XMLStreamUtil.isStartTag(reader, "time-range")) {
if (XMLStreamUtil.isStartTag(reader, "comp-filter")) {
String name = reader.getAttributeValue(null, "name");
if ("VEVENT".equals(name)) {
vEventOnly = true;
} else if ("VTODO".equals(name)) {
vTodoOnly = true;
}
} else if (XMLStreamUtil.isStartTag(reader, "time-range")) {
timeRangeStart = reader.getAttributeValue(null, "start");
timeRangeEnd = reader.getAttributeValue(null, "end");
}

View File

@ -2089,9 +2089,9 @@ public abstract class ExchangeSession {
writer.writeHeader("Date", new Date());
// Make sure invites have a proper subject line
String subject = vCalendar.getFirstVeventPropertyValue("SUMMARY");
if (subject == null) {
subject = BundleMessage.format("MEETING_REQUEST");
String vEventSubject = vCalendar.getFirstVeventPropertyValue("SUMMARY");
if (vEventSubject == null) {
vEventSubject = BundleMessage.format("MEETING_REQUEST");
}
// Write a part of the message that contains the
@ -2267,7 +2267,25 @@ public abstract class ExchangeSession {
dateCondition = gt("dtstart", formatSearchDate(cal.getTime()));
}
return searchEvents(folderPath, dateCondition);
return searchEvents(folderPath, or(isNull("instancetype"),
isEqualTo("instancetype", 1),
and(isEqualTo("instancetype", 0), dateCondition)));
}
protected Condition getRangeCondition(String timeRangeStart, String timeRangeEnd) throws IOException {
try {
SimpleDateFormat parser = getZuluDateFormat();
ExchangeSession.MultiCondition andCondition = and();
if (timeRangeStart != null) {
andCondition.add(gte("dtstart", formatSearchDate(parser.parse(timeRangeStart))));
}
if (timeRangeEnd != null) {
andCondition.add(lte("dtend", formatSearchDate(parser.parse(timeRangeEnd))));
}
return andCondition;
} catch (ParseException e) {
throw new IOException(e);
}
}
/**
@ -2280,30 +2298,47 @@ public abstract class ExchangeSession {
* @throws IOException on error
*/
public List<Event> searchEvents(String folderPath, String timeRangeStart, String timeRangeEnd) throws IOException {
try {
SimpleDateFormat parser = getZuluDateFormat();
ExchangeSession.MultiCondition andCondition = and();
if (timeRangeStart != null) {
andCondition.add(gte("dtstart", formatSearchDate(parser.parse(timeRangeStart))));
}
if (timeRangeEnd != null) {
andCondition.add(lte("dtend", formatSearchDate(parser.parse(timeRangeEnd))));
}
return searchEvents(folderPath, andCondition);
} catch (ParseException e) {
throw new IOException(e);
}
Condition dateCondition = getRangeCondition(timeRangeStart, timeRangeEnd);
return searchEvents(folderPath, or(isNull("instancetype"),
isEqualTo("instancetype", 1),
and(isEqualTo("instancetype", 0), dateCondition)));
}
/**
* Search events between start and end, exclude tasks.
*
* @param folderPath Exchange folder path
* @param timeRangeStart date range start in zulu format
* @param timeRangeEnd date range start in zulu format
* @return list of calendar events
* @throws IOException on error
*/
public List<Event> searchEventsOnly(String folderPath, String timeRangeStart, String timeRangeEnd) throws IOException {
Condition dateCondition = getRangeCondition(timeRangeStart, timeRangeEnd);
return searchEvents(folderPath, or(isEqualTo("instancetype", 1),
and(isEqualTo("instancetype", 0), dateCondition)));
}
/**
* Search tasks only (VTODO).
*
* @param folderPath Exchange folder path
* @return list of calendar events
* @throws IOException on error
*/
public List<Event> searchTasksOnly(String folderPath) throws IOException {
return searchEvents(folderPath, isNull("instancetype"));
}
/**
* Search calendar events in provided folder.
*
* @param folderPath Exchange folder path
* @param dateCondition date filter
* @param folderPath Exchange folder path
* @param filter search filter
* @return list of calendar events
* @throws IOException on error
*/
public List<Event> searchEvents(String folderPath, Condition dateCondition) throws IOException {
public List<Event> searchEvents(String folderPath, Condition filter) throws IOException {
Condition privateCondition = null;
if (isSharedFolder(folderPath)) {
@ -2312,10 +2347,7 @@ public abstract class ExchangeSession {
}
// instancetype 0 single appointment / 1 master recurring appointment
return searchEvents(folderPath, ITEM_PROPERTIES,
and(or(isNull("instancetype"),
isEqualTo("instancetype", 1),
and(isEqualTo("instancetype", 0), dateCondition)),
privateCondition));
and(filter, privateCondition));
}
/**

View File

@ -33,12 +33,16 @@ import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.MultiStatusResponse;
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import org.apache.log4j.Level;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* Test Caldav listener.
@ -121,6 +125,13 @@ public class TestCaldav extends AbstractDavMailTestCase {
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testGetOtherUserCalendar() throws IOException {
Settings.setLoggingLevel("httpclient.wire", Level.DEBUG);
PropFindMethod method = new PropFindMethod("/principals/users/" + Settings.getProperty("davmail.to") + "/calendar/");
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_OK, method.getStatusCode());
}
public void testReportCalendar() throws IOException, DavException {
SimpleDateFormat formatter = ExchangeSession.getZuluDateFormat();
Calendar cal = Calendar.getInstance();
@ -148,17 +159,60 @@ public class TestCaldav extends AbstractDavMailTestCase {
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
ExchangeSession.Condition dateCondition = session.and(
session.gt("dtstart", session.formatSearchDate(start)),
session.lt("dtend", session.formatSearchDate(end))
);
List<ExchangeSession.Event> events = session.searchEvents("/users/" + session.getEmail() + "/calendar/",
session.and(
session.gt("dtstart", session.formatSearchDate(start)),
session.lt("dtend", session.formatSearchDate(end))
)
session.or(session.isNull("instancetype"),
session.isEqualTo("instancetype", 1),
session.and(session.isEqualTo("instancetype", 0), dateCondition))
);
assertEquals(events.size(), responses.length);
}
public void testReportTasks() throws IOException, DavException {
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:D=\"DAV:\">");
buffer.append("<D:prop>");
buffer.append("<C:calendar-data/>");
buffer.append("</D:prop>");
buffer.append("<C:comp-filter name=\"VCALENDAR\">");
buffer.append("<C:comp-filter name=\"VTODO\"/>");
buffer.append("</C:comp-filter>");
buffer.append("<C:filter>");
buffer.append("</C:filter>");
buffer.append("</C:calendar-query>");
SearchReportMethod method = new SearchReportMethod("/users/" + session.getEmail() + "/calendar/", buffer.toString());
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
}
public void testReportEventsOnly() throws IOException, DavException {
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
buffer.append("<C:calendar-query xmlns:C=\"urn:ietf:params:xml:ns:caldav\" xmlns:D=\"DAV:\">");
buffer.append("<D:prop>");
buffer.append("<C:calendar-data/>");
buffer.append("</D:prop>");
buffer.append("<C:comp-filter name=\"VCALENDAR\">");
buffer.append("<C:comp-filter name=\"VEVENT\"/>");
buffer.append("</C:comp-filter>");
buffer.append("<C:filter>");
buffer.append("</C:filter>");
buffer.append("</C:calendar-query>");
SearchReportMethod method = new SearchReportMethod("/users/" + session.getEmail() + "/calendar/", buffer.toString());
httpClient.executeMethod(method);
assertEquals(HttpStatus.SC_MULTI_STATUS, method.getStatusCode());
MultiStatus multiStatus = method.getResponseBodyAsMultiStatus();
MultiStatusResponse[] responses = multiStatus.getResponses();
}
public void testCreateCalendar() throws IOException {
String folderName = "test & accentué";
String encodedFolderpath = URIUtil.encodePath("/users/" + session.getEmail() + "/calendar/" + folderName + '/');