1
0
mirror of https://github.com/moparisthebest/davmail synced 2024-08-13 16:53:51 -04:00

Caldav: Replace substrings with real MIME message parser to retrieve events, handle ics objects in Inbox

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@398 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2009-02-25 10:23:07 +00:00
parent 49b4301ce0
commit 9bd3a96b13
2 changed files with 56 additions and 44 deletions

View File

@ -175,7 +175,7 @@ public class CaldavConnection extends AbstractConnection {
public void handleRequest(String command, String path, Map<String, String> headers, String body) throws IOException {
int depth = getDepth(headers);
String[] paths = path.split("/");
String[] paths = path.replaceAll("//", "/").split("/");
// full debug trace
if (wireLogger.isDebugEnabled()) {
@ -216,7 +216,7 @@ public class CaldavConnection extends AbstractConnection {
} else if ("PROPFIND".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "inbox".equals(paths[3])) {
sendInbox(request, depth, paths[2]);
} else if ("REPORT".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "inbox".equals(paths[3])) {
reportEvents(request);
reportEvents(request, "INBOX");
} else if ("PROPFIND".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
sendOutbox(request, paths[2]);
} else if ("POST".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
@ -231,7 +231,7 @@ public class CaldavConnection extends AbstractConnection {
} else if ("REPORT".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "calendar".equals(paths[3])
// only current user for now
&& session.getEmail().equalsIgnoreCase(paths[2])) {
reportEvents(request);
reportEvents(request, "calendar");
} else if ("PUT".equals(command) && "users".equals(paths[1]) && paths.length == 5 && "calendar".equals(paths[3])
// only current user for now
@ -247,15 +247,18 @@ public class CaldavConnection extends AbstractConnection {
sendHttpResponse(eventResult.status, true);
}
} else if ("DELETE".equals(command) && "users".equals(paths[1]) && paths.length == 5 && "calendar".equals(paths[3])
} else if ("DELETE".equals(command) && "users".equals(paths[1]) && paths.length == 5
// only current user for now
&& session.getEmail().equalsIgnoreCase(paths[2])) {
int status = session.deleteEvent(paths[4]);
if ("inbox".equals(paths[3])) {
paths[3] = "INBOX";
}
int status = session.deleteEvent(paths[3]+"/"+paths[4]);
sendHttpResponse(status, true);
} else if ("GET".equals(command) && "users".equals(paths[1]) && paths.length == 5 && "calendar".equals(paths[3])
// only current user for now
&& session.getEmail().equalsIgnoreCase(paths[2])) {
ExchangeSession.Event event = session.getEvent(paths[4]);
ExchangeSession.Event event = session.getEvent(paths[3]+"/"+paths[4]);
sendHttpResponse(HttpStatus.SC_OK, null, "text/calendar;charset=UTF-8", event.getICS(), true);
} else {
@ -267,19 +270,19 @@ public class CaldavConnection extends AbstractConnection {
}
}
protected void appendEventsResponses(StringBuilder buffer, CaldavRequest request, List<ExchangeSession.Event> events) throws IOException {
protected void appendEventsResponses(StringBuilder buffer, CaldavRequest request, String path, List<ExchangeSession.Event> events) throws IOException {
int size = events.size();
int count = 0;
for (ExchangeSession.Event event : events) {
DavGatewayTray.debug("Retrieving event " + (++count) + "/" + size);
appendEventResponse(buffer, request, event);
appendEventResponse(buffer, request, path, event);
}
}
protected void appendEventResponse(StringBuilder buffer, CaldavRequest request, ExchangeSession.Event event) throws IOException {
protected void appendEventResponse(StringBuilder buffer, CaldavRequest request, String path, ExchangeSession.Event event) throws IOException {
String eventPath = event.getPath().replaceAll("<", "&lt;").replaceAll(">", "&gt;");
buffer.append("<D:response>");
buffer.append("<D:href>/users/").append(session.getEmail()).append("/calendar").append(URIUtil.encodeWithinQuery(eventPath)).append("</D:href>");
buffer.append("<D:href>/users/").append(session.getEmail()).append("/").append(path).append("/").append(URIUtil.encodeWithinQuery(eventPath)).append("</D:href>");
buffer.append("<D:propstat>");
buffer.append("<D:prop>");
if (request.hasProperty("calendar-data")) {
@ -408,7 +411,7 @@ public class CaldavConnection extends AbstractConnection {
DavGatewayTray.debug("Searching calendar messages...");
List<ExchangeSession.Event> events = session.getEventMessages();
DavGatewayTray.debug("Found " + events.size() + " calendar messages");
appendEventsResponses(buffer, request, events);
appendEventsResponses(buffer, request, "inbox", events);
}
buffer.append("</D:multistatus>");
sendHttpResponse(HttpStatus.SC_MULTI_STATUS, null, "text/xml;charset=UTF-8", buffer.toString(), true);
@ -432,22 +435,22 @@ public class CaldavConnection extends AbstractConnection {
DavGatewayTray.debug("Searching calendar events...");
List<ExchangeSession.Event> events = session.getAllEvents();
DavGatewayTray.debug("Found " + events.size() + " calendar events");
appendEventsResponses(buffer, request, events);
appendEventsResponses(buffer, request, "calendar", events);
}
buffer.append("</D:multistatus>");
sendHttpResponse(HttpStatus.SC_MULTI_STATUS, null, "text/xml;charset=UTF-8", buffer.toString(), true);
}
protected String getEventFileNameFromPath(String path) {
int index = path.indexOf("/calendar/");
int index = path.lastIndexOf('/');
if (index < 0) {
return null;
} else {
return path.substring(index + "/calendar/".length());
return path.substring(index + 1);
}
}
public void reportEvents(CaldavRequest request) throws IOException {
public void reportEvents(CaldavRequest request, String path) throws IOException {
List<ExchangeSession.Event> events;
List<String> notFound = new ArrayList<String>();
if (request.isMultiGet()) {
@ -461,12 +464,14 @@ public class CaldavConnection extends AbstractConnection {
if (eventName == null) {
notFound.add(href);
} else {
events.add(session.getEvent(eventName));
events.add(session.getEvent(path+"/"+eventName));
}
} catch (HttpException e) {
notFound.add(href);
}
}
} else if ("INBOX".equals(path)){
events = session.getEventMessages();
} else {
events = session.getAllEvents();
}
@ -474,7 +479,7 @@ public class CaldavConnection extends AbstractConnection {
StringBuilder buffer = new StringBuilder();
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<D:multistatus xmlns:D=\"DAV:\">");
appendEventsResponses(buffer, request, events);
appendEventsResponses(buffer, request, path, events);
// send not found events errors
for (String href : notFound) {

View File

@ -21,6 +21,11 @@ import org.htmlcleaner.CommentToken;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeBodyPart;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
@ -815,6 +820,8 @@ public class ExchangeSession {
folderPath = folderName.replaceFirst("Drafts", draftsUrl);
} else if (folderName.startsWith("Sent")) {
folderPath = folderName.replaceFirst("Sent", sentitemsUrl);
} else if (folderName.startsWith("calendar")) {
folderPath = folderName.replaceFirst("calendar", calendarUrl);
// absolute folder path
} else if (folderName.startsWith("/")) {
folderPath = folderName;
@ -1069,7 +1076,6 @@ public class ExchangeSession {
URIUtil.encodePath(destination));
method.addRequestHeader("Overwrite", "f");
method.addRequestHeader("Allow-rename", "t");
method.setDebug(4);
int status = wdr.retrieveSessionInstance().executeMethod(method);
if (status != HttpStatus.SC_CREATED) {
@ -1118,49 +1124,50 @@ public class ExchangeSession {
protected String etag;
public String getICS() throws IOException {
String result = null;
LOGGER.debug("Get event: " + href);
StringBuilder buffer = new StringBuilder();
GetMethod method = new GetMethod(URIUtil.encodePath(href));
method.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
method.setRequestHeader("Translate", "f");
BufferedReader eventReader = null;
try {
int status = wdr.retrieveSessionInstance().executeMethod(method);
if (status != HttpStatus.SC_OK) {
LOGGER.warn("Unable to get event at " + href + " status: " + status);
}
eventReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
String line;
boolean inbody = false;
while ((line = eventReader.readLine()) != null) {
if ("BEGIN:VCALENDAR".equals(line)) {
inbody = true;
}
if (inbody) {
buffer.append(line);
buffer.append((char) 13);
buffer.append((char) 10);
}
if ("END:VCALENDAR".equals(line)) {
inbody = false;
MimeMessage mimeMessage = new MimeMessage(null, method.getResponseBodyAsStream());
MimeMultipart multiPart = (MimeMultipart) mimeMessage.getContent();
MimeBodyPart bodyPart = null;
for (int i = 0; i < multiPart.getCount(); i++) {
String contentType = multiPart.getBodyPart(i).getContentType();
if (contentType.startsWith("text/calendar") || contentType.startsWith("application/ics") ) {
bodyPart = (MimeBodyPart) multiPart.getBodyPart(i);
}
}
} finally {
if (eventReader != null) {
try {
eventReader.close();
} catch (IOException e) {
LOGGER.error("Error parsing event at " + method.getPath());
}
if (bodyPart == null) {
throw new IOException("Invalid message content");
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bodyPart.getDataHandler().writeTo(baos);
baos.close();
result = fixICS(new String(baos.toByteArray(), "UTF-8"), true);
} catch (MessagingException e) {
throw new IOException(e.getMessage());
} finally {
method.releaseConnection();
}
return fixICS(buffer.toString(), true);
return result;
}
public String getPath() {
return href.substring(calendarUrl.length());
int index = href.lastIndexOf('/');
if (index >= 0) {
return href.substring(index + 1);
} else {
return href;
}
}
public String getEtag() {
@ -1225,7 +1232,7 @@ public class ExchangeSession {
}
public Event getEvent(String path) throws IOException {
Enumeration calendarEnum = wdr.propfindMethod(calendarUrl + "/" + URIUtil.decode(path), 0, EVENT_REQUEST_PROPERTIES);
Enumeration calendarEnum = wdr.propfindMethod(getFolderPath(URIUtil.decode(path)), 0, EVENT_REQUEST_PROPERTIES);
if (!calendarEnum.hasMoreElements()) {
throw new IOException("Unable to get calendar event");
}
@ -1563,7 +1570,7 @@ public class ExchangeSession {
}
public int deleteEvent(String path) throws IOException {
wdr.deleteMethod(calendarUrl + "/" + URIUtil.decode(path));
wdr.deleteMethod(getFolderPath(URIUtil.decode(path)));
return wdr.getStatusCode();
}