From c114edda334ab00dc9a10f98dfab9fcdf525fe44 Mon Sep 17 00:00:00 2001 From: mguessan Date: Thu, 13 Aug 2009 08:34:51 +0000 Subject: [PATCH] Doc: improve javadoc git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@669 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- src/java/davmail/caldav/CaldavConnection.java | 4 +- src/java/davmail/caldav/CaldavServer.java | 3 + .../DavMailAuthenticationException.java | 6 +- .../davmail/exchange/ExchangeSession.java | 211 +++++++++++++++--- 4 files changed, 185 insertions(+), 39 deletions(-) diff --git a/src/java/davmail/caldav/CaldavConnection.java b/src/java/davmail/caldav/CaldavConnection.java index d28a86b4..e69b67a7 100644 --- a/src/java/davmail/caldav/CaldavConnection.java +++ b/src/java/davmail/caldav/CaldavConnection.java @@ -310,7 +310,7 @@ public class CaldavConnection extends AbstractConnection { if (!(eventPath.charAt(eventPath.length() - 1) == '/')) { eventPath.append('/'); } - String eventName = xmlEncodeName(event.getPath()); + String eventName = xmlEncodeName(event.getName()); eventPath.append(URIUtil.encodeWithinQuery(eventName)); response.startResponse(eventPath.toString()); response.startPropstat(); @@ -779,7 +779,7 @@ public class CaldavConnection extends AbstractConnection { // get freebusy for each attendee HashMap freeBusyMap = new HashMap(); for (String attendee : attendees) { - ExchangeSession.FreeBusy freeBusy = session.getFreebusy(attendee, valueMap); + ExchangeSession.FreeBusy freeBusy = session.getFreebusy(attendee, valueMap.get("DTSTART"), valueMap.get("DTEND")); if (freeBusy != null) { freeBusyMap.put(attendee, freeBusy); } diff --git a/src/java/davmail/caldav/CaldavServer.java b/src/java/davmail/caldav/CaldavServer.java index b961b367..2881bae4 100644 --- a/src/java/davmail/caldav/CaldavServer.java +++ b/src/java/davmail/caldav/CaldavServer.java @@ -27,6 +27,9 @@ import java.net.Socket; * Calendar server, handle HTTP Caldav requests. */ public class CaldavServer extends AbstractServer { + /** + * Default HTTP Caldav port + */ public static final int DEFAULT_PORT = 80; /** diff --git a/src/java/davmail/exception/DavMailAuthenticationException.java b/src/java/davmail/exception/DavMailAuthenticationException.java index bbe15866..d2740141 100644 --- a/src/java/davmail/exception/DavMailAuthenticationException.java +++ b/src/java/davmail/exception/DavMailAuthenticationException.java @@ -18,12 +18,14 @@ */ package davmail.exception; -import davmail.exception.DavMailException; - /** * I18 AuthenticationException subclass. */ public class DavMailAuthenticationException extends DavMailException { + /** + * Create a DavMail exception with the given BundleMessage key + * @param key message key + */ public DavMailAuthenticationException(String key) { super(key); } diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 34b23a7f..bb2e98fd 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -971,7 +971,7 @@ public class ExchangeSession { } /** - * Create Exchange folder + * Create Exchange folder. * * @param folderName logical folder name * @throws IOException on error @@ -994,6 +994,16 @@ public class ExchangeSession { } } + /** + * Delete Exchange folder. + * + * @param folderName logical folder name + * @throws IOException on error + */ + public void deleteFolder(String folderName) throws IOException { + DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, URIUtil.encodePath(getFolderPath(folderName))); + } + /** * Copy message to target folder * @@ -1393,6 +1403,9 @@ public class ExchangeSession { public static class MessageList extends ArrayList { } + /** + * Calendar event object + */ public class Event { protected String href; protected String etag; @@ -1415,6 +1428,12 @@ public class ExchangeSession { return bodyPart; } + /** + * Load ICS content from Exchange server. + * User Translate: f header to get MIME event content and get ICS attachment from it + * @return ICS (iCalendar) event + * @throws IOException on error + */ public String getICS() throws IOException { String result = null; LOGGER.debug("Get event: " + href); @@ -1455,7 +1474,11 @@ public class ExchangeSession { return result; } - public String getPath() { + /** + * Get event name (file name part in URL). + * @return event name + */ + public String getName() { int index = href.lastIndexOf('/'); if (index >= 0) { return href.substring(index + 1); @@ -1464,11 +1487,21 @@ public class ExchangeSession { } } + /** + * Get event etag (last change tag). + * @return event etag + */ public String getEtag() { return etag; } } + /** + * Search calendar messages in provided folder. + * @param folderPath Exchange folder path + * @return list of calendar messages as Event objects + * @throws IOException on error + */ public List getEventMessages(String folderPath) throws IOException { String searchQuery = "Select \"DAV:getetag\"" + " FROM Scope('SHALLOW TRAVERSAL OF \"" + folderPath + "\"')\n" + @@ -1478,6 +1511,12 @@ public class ExchangeSession { return getEvents(folderPath, searchQuery); } + /** + * Search calendar events in provided folder. + * @param folderPath Exchange folder path + * @return list of calendar events + * @throws IOException on error + */ public List getAllEvents(String folderPath) throws IOException { int caldavPastDelay = Settings.getIntProperty("davmail.caldavPastDelay", Integer.MAX_VALUE); String dateCondition = ""; @@ -1499,17 +1538,32 @@ public class ExchangeSession { return getEvents(folderPath, searchQuery); } - public List getEvents(String path, String searchQuery) throws IOException { + + /** + * Search calendar events or messages in provided folder matching the search query. + * @param folderPath Exchange folder path + * @param searchQuery Exchange search query + * @return list of calendar messages as Event objects + * @throws IOException on error + */ + protected List getEvents(String folderPath, String searchQuery) throws IOException { List events = new ArrayList(); - MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executeSearchMethod(httpClient, URIUtil.encodePath(path), searchQuery); + MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executeSearchMethod(httpClient, URIUtil.encodePath(folderPath), searchQuery); for (MultiStatusResponse response : responses) { events.add(buildEvent(response)); } return events; } - public Event getEvent(String path, String eventName) throws IOException { - String eventPath = URIUtil.encodePath(path + '/' + eventName); + /** + * Get event named eventName in folder + * @param folderPath Exchange folder path + * @param eventName event name + * @return event object + * @throws IOException on error + */ + public Event getEvent(String folderPath, String eventName) throws IOException { + String eventPath = URIUtil.encodePath(folderPath + '/' + eventName); MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executePropFindMethod(httpClient, eventPath, 0, EVENT_REQUEST_PROPERTIES); if (responses.length == 0) { throw new DavMailException("EXCEPTION_EVENT_NOT_FOUND"); @@ -1517,6 +1571,30 @@ public class ExchangeSession { return buildEvent(responses[0]); } + /** + * Delete event named eventName in folder + * @param folderPath Exchange folder path + * @param eventName event name + * @return HTTP status + * @throws IOException on error + */ + public int deleteEvent(String folderPath, String eventName) throws IOException { + String eventPath = URIUtil.encodePath(folderPath + '/' + eventName); + int status; + if (inboxUrl.endsWith(folderPath)) { + // do not delete calendar messages, mark read and processed + ArrayList list = new ArrayList(); + list.add(new DefaultDavProperty(DavPropertyName.create("schedule-state", Namespace.getNamespace("CALDAV:")), "CALDAV:schedule-processed")); + list.add(new DefaultDavProperty(DavPropertyName.create("read", URN_SCHEMAS_HTTPMAIL), "1")); + PropPatchMethod patchMethod = new PropPatchMethod(eventPath, list); + DavGatewayHttpClientFacade.executeMethod(httpClient, patchMethod); + status = HttpStatus.SC_OK; + } else { + status = DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, eventPath); + } + return status; + } + protected Event buildEvent(MultiStatusResponse calendarResponse) throws URIException { Event event = new Event(); String href = calendarResponse.getHref(); @@ -1581,7 +1659,7 @@ public class ExchangeSession { } catch (MissingResourceException mre) { LOGGER.warn(new BundleMessage("LOG_INVALID_TIMEZONE", value)); } - } else if (key.equals("X-MICROSOFT-CDO-BUSYSTATUS")) { + } else if ("X-MICROSOFT-CDO-BUSYSTATUS".equals(key)) { hasCdoBusyStatus = true; } } @@ -1712,11 +1790,26 @@ public class ExchangeSession { } + /** + * Event result object to hold HTTP status and event etag from an event creation/update. + */ public static class EventResult { + /** + * HTTP status + */ public int status; + /** + * Event etag from response HTTP header + */ public String etag; } + /** + * Build and send the MIME message for the provided ICS event. + * @param icsBody event in iCalendar format + * @return HTTP status + * @throws IOException on error + */ public int sendEvent(String icsBody) throws IOException { String messageUrl = URIUtil.encodePathQuery(draftsUrl + '/' + UUID.randomUUID().toString() + ".EML"); int status = internalCreateOrUpdateEvent(messageUrl, "urn:content-classes:calendarmessage", icsBody, null, null).status; @@ -1732,8 +1825,18 @@ public class ExchangeSession { } } - public EventResult createOrUpdateEvent(String path, String eventName, String icsBody, String etag, String noneMatch) throws IOException { - String messageUrl = URIUtil.encodePath(path + '/' + eventName); + /** + * Create or update event on the Exchange server + * @param folderPath Exchange folder path + * @param eventName event name + * @param icsBody event body in iCalendar format + * @param etag previous event etag to detect concurrent updates + * @param noneMatch if-none-match header value + * @return HTTP response event result (status and etag) + * @throws IOException on error + */ + public EventResult createOrUpdateEvent(String folderPath, String eventName, String icsBody, String etag, String noneMatch) throws IOException { + String messageUrl = URIUtil.encodePath(folderPath + '/' + eventName); return internalCreateOrUpdateEvent(messageUrl, "urn:content-classes:appointment", icsBody, etag, noneMatch); } @@ -1936,37 +2039,31 @@ public class ExchangeSession { return eventResult; } - - public void deleteFolder(String path) throws IOException { - DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, URIUtil.encodePath(getFolderPath(path))); - } - - public int deleteEvent(String path, String eventName) throws IOException { - String eventPath = URIUtil.encodePath(path + '/' + eventName); - int status; - if (inboxUrl.endsWith(path)) { - // do not delete calendar messages, mark read and processed - ArrayList list = new ArrayList(); - list.add(new DefaultDavProperty(DavPropertyName.create("schedule-state", Namespace.getNamespace("CALDAV:")), "CALDAV:schedule-processed")); - list.add(new DefaultDavProperty(DavPropertyName.create("read", URN_SCHEMAS_HTTPMAIL), "1")); - PropPatchMethod patchMethod = new PropPatchMethod(eventPath, list); - DavGatewayHttpClientFacade.executeMethod(httpClient, patchMethod); - status = HttpStatus.SC_OK; - } else { - status = DavGatewayHttpClientFacade.executeDeleteMethod(httpClient, eventPath); - } - return status; - } - + /** + * Get folder ctag (change tag). + * This flag changes whenever folder or folder content changes + * + * @param folderPath Exchange folder path + * @return folder ctag + * @throws IOException on error + */ public String getFolderCtag(String folderPath) throws IOException { return getFolderProperty(folderPath, CONTENT_TAG); } + /** + * Get folder resource tag. + * Same as etag for folders, changes when folder (not content) changes + * + * @param folderPath Exchange folder path + * @return folder resource tag + * @throws IOException on error + */ public String getFolderResourceTag(String folderPath) throws IOException { return getFolderProperty(folderPath, RESOURCE_TAG); } - public String getFolderProperty(String folderPath, DavPropertyNameSet davPropertyNameSet) throws IOException { + protected String getFolderProperty(String folderPath, DavPropertyNameSet davPropertyNameSet) throws IOException { String result; MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executePropFindMethod( httpClient, URIUtil.encodePath(folderPath), 0, davPropertyNameSet); @@ -2015,6 +2112,10 @@ public class ExchangeSession { } } + /** + * Get user alias from mailbox display name over Webdav. + * @return user alias + */ public String getAliasFromMailboxDisplayName() { if (mailPath == null) { return null; @@ -2034,6 +2135,17 @@ public class ExchangeSession { return displayName; } + /** + * Build Caldav calendar path for principal and folder name. + * - prefix is current user mailbox path if principal is current user, + * else prefix is parent folder of current user mailbox path followed by principal + * - suffix according to well known folder names (internationalized on Exchange) + * + * @param principal calendar principal + * @param folderName requested folder name + * @return Exchange folder path + * @throws IOException on error + */ public String buildCalendarPath(String principal, String folderName) throws IOException { StringBuilder buffer = new StringBuilder(); if (principal != null && !alias.equals(principal) && !email.equals(principal)) { @@ -2070,6 +2182,12 @@ public class ExchangeSession { } } + /** + * Get user email from global address list (galfind). + * + * @param alias user alias + * @return user email + */ public String getEmail(String alias) { String emailResult = null; if (alias != null) { @@ -2098,6 +2216,12 @@ public class ExchangeSession { return emailResult; } + /** + * Determine user email through various means. + * + * @param hostName Exchange server host name for last failover + * @param methodPath current httpclient method path + */ public void buildEmail(String hostName, String methodPath) { // first try to get email from login name alias = getAliasFromLogin(); @@ -2259,6 +2383,12 @@ public class ExchangeSession { return results; } + /** + * Get extended address book information for person with gallookup. + * Does not work with Exchange 2007 + * + * @param person person attributes map + */ public void galLookup(Map person) { if (!disableGalLookup) { GetMethod getMethod = null; @@ -2287,10 +2417,17 @@ public class ExchangeSession { } } - public FreeBusy getFreebusy(String attendee, Map valueMap) throws IOException { + /** + * Get freebusy info for attendee between start and end date. + * + * @param attendee attendee email + * @param startDateValue start date + * @param endDateValue end date + * @return FreeBusy info + * @throws IOException on error + */ + public FreeBusy getFreebusy(String attendee, String startDateValue, String endDateValue) throws IOException { - String startDateValue = valueMap.get("DTSTART"); - String endDateValue = valueMap.get("DTEND"); if (attendee.startsWith("mailto:")) { attendee = attendee.substring("mailto:".length()); } @@ -2415,6 +2552,10 @@ public class ExchangeSession { } } + /** + * Append freebusy information to buffer. + * @param buffer String buffer + */ public void appendTo(StringBuilder buffer) { for (Map.Entry entry : busyMap.entrySet()) { buffer.append("FREEBUSY;FBTYPE=").append(entry.getKey())