diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java
index b7f1660f..228a180a 100644
--- a/src/java/davmail/exchange/ExchangeSession.java
+++ b/src/java/davmail/exchange/ExchangeSession.java
@@ -111,6 +111,11 @@ public abstract class ExchangeSession {
protected String rootPath;
protected String email;
protected String alias;
+ /**
+ * Lower case Caldav path to current user mailbox.
+ * /users/email
+ */
+ protected String currentMailboxPath;
protected final HttpClient httpClient;
private final String userName;
@@ -238,7 +243,20 @@ public abstract class ExchangeSession {
* @throws NoRouteToHostException on error
* @throws UnknownHostException on error
*/
- public abstract boolean isExpired() throws NoRouteToHostException, UnknownHostException;
+ public boolean isExpired() throws NoRouteToHostException, UnknownHostException {
+ boolean isExpired = false;
+ try {
+ getFolder("");
+ } catch (UnknownHostException exc) {
+ throw exc;
+ } catch (NoRouteToHostException exc) {
+ throw exc;
+ } catch (IOException e) {
+ isExpired = true;
+ }
+
+ return isExpired;
+ }
/**
* Test authentication mode : form based or basic.
@@ -1001,8 +1019,8 @@ public abstract class ExchangeSession {
* Create Exchange message folder.
*
* @param folderName logical folder name
- * @throws IOException on error
* @return status
+ * @throws IOException on error
*/
public int createMessageFolder(String folderName) throws IOException {
return createFolder(folderName, "IPF.Note", null);
@@ -1013,8 +1031,8 @@ public abstract class ExchangeSession {
*
* @param folderName logical folder name
* @param properties folder properties
- * @throws IOException on error
* @return status
+ * @throws IOException on error
*/
public int createCalendarFolder(String folderName, Map properties) throws IOException {
return createFolder(folderName, "IPF.Appointment", properties);
@@ -1025,8 +1043,8 @@ public abstract class ExchangeSession {
*
* @param folderName logical folder name
* @param properties folder properties
- * @throws IOException on error
* @return status
+ * @throws IOException on error
*/
public int createContactFolder(String folderName, Map properties) throws IOException {
return createFolder(folderName, "IPF.Contact", properties);
@@ -1037,7 +1055,7 @@ public abstract class ExchangeSession {
*
* @param folderName logical folder name
* @param folderClass folder class
- * @param properties folder properties
+ * @param properties folder properties
* @return status
* @throws IOException on error
*/
@@ -2526,7 +2544,7 @@ public abstract class ExchangeSession {
* @param folderPath Exchange folder path
* @param attributes requested attributes
* @param condition Exchange search query
- * @param maxCount maximum item count
+ * @param maxCount maximum item count
* @return list of contacts
* @throws IOException on error
*/
@@ -2809,7 +2827,7 @@ public abstract class ExchangeSession {
convertContactProperties(properties, VCARD_ADR_HOME_PROPERTIES, property.getValues());
} else if (property.hasParam("TYPE", "work")) {
convertContactProperties(properties, VCARD_ADR_WORK_PROPERTIES, property.getValues());
- // any other type goes to other address
+ // any other type goes to other address
} else {
convertContactProperties(properties, VCARD_ADR_OTHER_PROPERTIES, property.getValues());
}
@@ -3268,11 +3286,11 @@ public abstract class ExchangeSession {
CONTACT_ATTRIBUTES.add("haspicture");
CONTACT_ATTRIBUTES.add("keywords");
CONTACT_ATTRIBUTES.add("othermobile");
- CONTACT_ATTRIBUTES.add("otherTelephone");
+ CONTACT_ATTRIBUTES.add("otherTelephone");
CONTACT_ATTRIBUTES.add("gender");
CONTACT_ATTRIBUTES.add("private");
CONTACT_ATTRIBUTES.add("sensitivity");
- CONTACT_ATTRIBUTES.add("fburl");
+ CONTACT_ATTRIBUTES.add("fburl");
}
/**
@@ -3308,6 +3326,17 @@ public abstract class ExchangeSession {
}
}
+ /**
+ * Get freebusy data string from Exchange.
+ *
+ * @param attendee attendee email address
+ * @param start start date in Exchange zulu format
+ * @param end end date in Exchange zulu format
+ * @param interval freebusy interval in minutes
+ * @return freebusy data or null
+ */
+ protected abstract String getFreeBusyData(String attendee, String start, String end, int interval) throws IOException;
+
/**
* Get freebusy info for attendee between start and end date.
*
@@ -3326,7 +3355,6 @@ public abstract class ExchangeSession {
SimpleDateFormat exchangeZuluDateFormat = getExchangeZuluDateFormat();
SimpleDateFormat icalDateFormat = getZuluDateFormat();
- String freebusyUrl;
Date startDate;
Date endDate;
try {
@@ -3340,27 +3368,14 @@ public abstract class ExchangeSession {
} else {
endDate = icalDateFormat.parse(endDateValue);
}
- freebusyUrl = publicFolderUrl + "/?cmd=freebusy" +
- "&start=" + exchangeZuluDateFormat.format(startDate) +
- "&end=" + exchangeZuluDateFormat.format(endDate) +
- "&interval=" + FREE_BUSY_INTERVAL +
- "&u=SMTP:" + attendee;
} catch (ParseException e) {
throw new DavMailException("EXCEPTION_INVALID_DATES", e.getMessage());
}
FreeBusy freeBusy = null;
- GetMethod getMethod = new GetMethod(freebusyUrl);
- getMethod.setRequestHeader("Content-Type", "text/xml");
-
- try {
- DavGatewayHttpClientFacade.executeGetMethod(httpClient, getMethod, true);
- String fbdata = StringUtil.getLastToken(getMethod.getResponseBodyAsString(), "", "");
- if (fbdata != null) {
- freeBusy = new FreeBusy(icalDateFormat, startDate, fbdata);
- }
- } finally {
- getMethod.releaseConnection();
+ String fbdata = getFreeBusyData(attendee, exchangeZuluDateFormat.format(startDate), exchangeZuluDateFormat.format(endDate), FREE_BUSY_INTERVAL);
+ if (fbdata != null) {
+ freeBusy = new FreeBusy(icalDateFormat, startDate, fbdata);
}
if (freeBusy != null && freeBusy.knownAttendee) {
diff --git a/src/java/davmail/exchange/dav/DavExchangeSession.java b/src/java/davmail/exchange/dav/DavExchangeSession.java
index 2d4dcbda..e164f36b 100644
--- a/src/java/davmail/exchange/dav/DavExchangeSession.java
+++ b/src/java/davmail/exchange/dav/DavExchangeSession.java
@@ -47,9 +47,7 @@ import org.w3c.dom.Node;
import javax.mail.MessagingException;
import java.io.*;
-import java.net.NoRouteToHostException;
import java.net.URL;
-import java.net.UnknownHostException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -174,6 +172,25 @@ public class DavExchangeSession extends ExchangeSession {
return !getFolderPath(folderPath).toLowerCase().startsWith(mailPath.toLowerCase());
}
+ @Override
+ protected String getFreeBusyData(String attendee, String start, String end, int interval) throws IOException {
+ String freebusyUrl = publicFolderUrl + "/?cmd=freebusy" +
+ "&start=" + start +
+ "&end=" + end +
+ "&interval=" + interval +
+ "&u=SMTP:" + attendee;
+ GetMethod getMethod = new GetMethod(freebusyUrl);
+ getMethod.setRequestHeader("Content-Type", "text/xml");
+ String fbdata = null;
+ try {
+ DavGatewayHttpClientFacade.executeGetMethod(httpClient, getMethod, true);
+ fbdata = StringUtil.getLastToken(getMethod.getResponseBodyAsString(), "", "");
+ } finally {
+ getMethod.releaseConnection();
+ }
+ return fbdata;
+ }
+
/**
* @inheritDoc
*/
@@ -335,25 +352,6 @@ public class DavExchangeSession extends ExchangeSession {
}
}
- /**
- * @inheritDoc
- */
- @Override
- public boolean isExpired() throws NoRouteToHostException, UnknownHostException {
- boolean isExpired = false;
- try {
- getFolder("");
- } catch (UnknownHostException exc) {
- throw exc;
- } catch (NoRouteToHostException exc) {
- throw exc;
- } catch (IOException e) {
- isExpired = true;
- }
-
- return isExpired;
- }
-
protected static class MultiCondition extends ExchangeSession.MultiCondition {
protected MultiCondition(Operator operator, Condition... condition) {
super(operator, condition);
diff --git a/src/java/davmail/exchange/ews/DistinguishedFolderId.java b/src/java/davmail/exchange/ews/DistinguishedFolderId.java
index 8af80d58..1ed127b6 100644
--- a/src/java/davmail/exchange/ews/DistinguishedFolderId.java
+++ b/src/java/davmail/exchange/ews/DistinguishedFolderId.java
@@ -18,6 +18,9 @@
*/
package davmail.exchange.ews;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Distinguished Folder Id.
*/
@@ -27,21 +30,40 @@ public class DistinguishedFolderId extends FolderId {
super("t:DistinguishedFolderId", value, null);
}
- public static final DistinguishedFolderId CALENDAR = new DistinguishedFolderId("calendar");
- public static final DistinguishedFolderId CONTACTS = new DistinguishedFolderId("contacts");
- public static final DistinguishedFolderId DELETEDITEMS = new DistinguishedFolderId("deleteditems");
- public static final DistinguishedFolderId DRAFTS = new DistinguishedFolderId("drafts");
- public static final DistinguishedFolderId INBOX = new DistinguishedFolderId("inbox");
- public static final DistinguishedFolderId JOURNAL = new DistinguishedFolderId("journal");
- public static final DistinguishedFolderId NOTES = new DistinguishedFolderId("notes");
- public static final DistinguishedFolderId OUTBOX = new DistinguishedFolderId("outbox");
- public static final DistinguishedFolderId SENTITEMS = new DistinguishedFolderId("sentitems");
- public static final DistinguishedFolderId TASKS = new DistinguishedFolderId("tasks");
- public static final DistinguishedFolderId MSGFOLDERROOT = new DistinguishedFolderId("msgfolderroot");
- public static final DistinguishedFolderId PUBLICFOLDERSROOT = new DistinguishedFolderId("publicfoldersroot");
- public static final DistinguishedFolderId ROOT = new DistinguishedFolderId("root");
- public static final DistinguishedFolderId JUNKEMAIL = new DistinguishedFolderId("junkemail");
- public static final DistinguishedFolderId SEARCHFOLDERS = new DistinguishedFolderId("searchfolders");
- public static final DistinguishedFolderId VOICEMAIL = new DistinguishedFolderId("voicemail");
+ private DistinguishedFolderId(String value, String mailbox) {
+ super("t:DistinguishedFolderId", value, null, mailbox);
+ }
+
+ /**
+ * DistinguishedFolderId names
+ */
+ @SuppressWarnings({"UnusedDeclaration", "JavaDoc"})
+ public static enum Name {
+ calendar, contacts, deleteditems, drafts, inbox, journal, notes, outbox, sentitems, tasks, msgfolderroot,
+ publicfoldersroot, root, junkemail, searchfolders, voicemail
+ }
+
+ protected static final Map folderIdMap = new HashMap();
+
+ static {
+ for (Name name : Name.values()) {
+ folderIdMap.put(name, new DistinguishedFolderId(name.toString()));
+ }
+ }
+
+ /**
+ * Get DistinguishedFolderId object for mailbox and name.
+ *
+ * @param mailbox mailbox name
+ * @param name folder id name
+ * @return DistinguishedFolderId object
+ */
+ public static DistinguishedFolderId getInstance(String mailbox, Name name) {
+ if (mailbox == null) {
+ return folderIdMap.get(name);
+ } else {
+ return new DistinguishedFolderId(name.toString(), mailbox);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/java/davmail/exchange/ews/EWSMethod.java b/src/java/davmail/exchange/ews/EWSMethod.java
index 6e59ea98..05b1501a 100644
--- a/src/java/davmail/exchange/ews/EWSMethod.java
+++ b/src/java/davmail/exchange/ews/EWSMethod.java
@@ -360,6 +360,7 @@ public abstract class EWSMethod extends PostMethod {
endChanges(writer);
}
+
protected void writeIndexedPageItemView(Writer writer) throws IOException {
if (maxCount > 0) {
writer.write("();
// load actual well known folder ids
@@ -114,9 +115,6 @@ public class EwsExchangeSession extends ExchangeSession {
throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE");
}
- // also need to retrieve email and alias
- alias = getAliasFromOptions();
- email = getEmailFromOptions();
}
class Message extends ExchangeSession.Message {
@@ -502,9 +500,9 @@ public class EwsExchangeSession extends ExchangeSession {
FOLDER_PROPERTIES.add(Field.get("highestUid"));
}
- protected Folder buildFolder(EWSMethod.Item item) {
+ protected Folder buildFolder(String mailbox, EWSMethod.Item item) {
Folder folder = new Folder();
- folder.folderId = new FolderId(item);
+ folder.folderId = new FolderId(mailbox, item);
folder.displayName = item.get(Field.get("folderDisplayName").getResponseName());
folder.folderClass = item.get(Field.get("folderclass").getResponseName());
folder.etag = item.get(Field.get("lastmodified").getResponseName());
@@ -540,7 +538,7 @@ public class EwsExchangeSession extends ExchangeSession {
BaseShape.ID_ONLY, parentFolderId, FOLDER_PROPERTIES, (SearchExpression) condition);
executeMethod(findFolderMethod);
for (EWSMethod.Item item : findFolderMethod.getResponseItems()) {
- Folder folder = buildFolder(item);
+ Folder folder = buildFolder(parentFolderId.mailbox, item);
if (parentFolderPath.length() > 0) {
folder.folderPath = parentFolderPath + '/' + item.get(Field.get("urlcompname").getResponseName());
} else if (folderIdMap.get(folder.folderId.value) != null) {
@@ -571,12 +569,13 @@ public class EwsExchangeSession extends ExchangeSession {
* @throws IOException on error
*/
protected EwsExchangeSession.Folder internalGetFolder(String folderPath) throws IOException {
- GetFolderMethod getFolderMethod = new GetFolderMethod(BaseShape.ID_ONLY, getFolderId(folderPath), FOLDER_PROPERTIES);
+ FolderId folderId = getFolderId(folderPath);
+ GetFolderMethod getFolderMethod = new GetFolderMethod(BaseShape.ID_ONLY, folderId, FOLDER_PROPERTIES);
executeMethod(getFolderMethod);
EWSMethod.Item item = getFolderMethod.getResponseItem();
Folder folder = null;
if (item != null) {
- folder = buildFolder(item);
+ folder = buildFolder(folderId.mailbox, item);
folder.folderPath = folderPath;
}
return folder;
@@ -1085,8 +1084,14 @@ public class EwsExchangeSession extends ExchangeSession {
@Override
public boolean isSharedFolder(String folderPath) {
- // TODO
- return false;
+ return folderPath.startsWith("/") && !folderPath.toLowerCase().startsWith(currentMailboxPath);
+ }
+
+ @Override
+ protected String getFreeBusyData(String attendee, String start, String end, int interval) throws IOException {
+ GetUserAvailabilityMethod getUserAvailabilityMethod = new GetUserAvailabilityMethod(attendee, start, end, interval);
+ executeMethod(getUserAvailabilityMethod);
+ return getUserAvailabilityMethod.getMergedFreeBusy();
}
@Override
@@ -1103,47 +1108,64 @@ public class EwsExchangeSession extends ExchangeSession {
return folderId;
}
- private FolderId getFolderIdIfExists(String folderPath) throws IOException {
+ protected static final String USERS_ROOT = "/users/";
+
+ protected FolderId getFolderIdIfExists(String folderPath) throws IOException {
+ String lowerCaseFolderPath = folderPath.toLowerCase();
+ if (currentMailboxPath.equals(lowerCaseFolderPath)) {
+ return getSubFolderIdIfExists(null, "");
+ } else if (lowerCaseFolderPath.startsWith(currentMailboxPath + '/')) {
+ return getSubFolderIdIfExists(null, folderPath.substring(currentMailboxPath.length() + 1));
+ } else if (folderPath.startsWith("/users/")) {
+ int slashIndex = folderPath.indexOf('/', USERS_ROOT.length());
+ String mailbox;
+ String subFolderPath;
+ if (slashIndex >= 0) {
+ mailbox = folderPath.substring(USERS_ROOT.length(), slashIndex);
+ subFolderPath = folderPath.substring(slashIndex+1);
+ } else {
+ mailbox = folderPath.substring(USERS_ROOT.length());
+ subFolderPath = "";
+ }
+ return getSubFolderIdIfExists(mailbox, subFolderPath);
+ } else {
+ return getSubFolderIdIfExists(null, folderPath);
+ }
+ }
+
+ protected FolderId getSubFolderIdIfExists(String mailbox, String folderPath) throws IOException {
String[] folderNames;
FolderId currentFolderId;
- String lowerCaseFolderPath = folderPath.toLowerCase();
- if (email != null) {
- String currentMailboxPath = "/users/" + email.toLowerCase();
- if (currentMailboxPath.equals(lowerCaseFolderPath)) {
- return DistinguishedFolderId.MSGFOLDERROOT;
- } else if (lowerCaseFolderPath.startsWith(currentMailboxPath + '/')) {
- return getFolderIdIfExists(folderPath.substring(currentMailboxPath.length() + 1));
- }
- }
+
if (folderPath.startsWith(PUBLIC_ROOT)) {
- currentFolderId = DistinguishedFolderId.PUBLICFOLDERSROOT;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.publicfoldersroot);
folderNames = folderPath.substring(PUBLIC_ROOT.length()).split("/");
} else if (folderPath.startsWith(INBOX) || folderPath.startsWith(LOWER_CASE_INBOX)) {
- currentFolderId = DistinguishedFolderId.INBOX;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.inbox);
folderNames = folderPath.substring(INBOX.length()).split("/");
} else if (folderPath.startsWith(CALENDAR)) {
- currentFolderId = DistinguishedFolderId.CALENDAR;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.calendar);
folderNames = folderPath.substring(CALENDAR.length()).split("/");
} else if (folderPath.startsWith(CONTACTS)) {
- currentFolderId = DistinguishedFolderId.CONTACTS;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.contacts);
folderNames = folderPath.substring(CONTACTS.length()).split("/");
} else if (folderPath.startsWith(SENT)) {
- currentFolderId = DistinguishedFolderId.SENTITEMS;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.sentitems);
folderNames = folderPath.substring(SENT.length()).split("/");
} else if (folderPath.startsWith(DRAFTS)) {
- currentFolderId = DistinguishedFolderId.DRAFTS;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.drafts);
folderNames = folderPath.substring(DRAFTS.length()).split("/");
} else if (folderPath.startsWith(TRASH)) {
- currentFolderId = DistinguishedFolderId.DELETEDITEMS;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.deleteditems);
folderNames = folderPath.substring(TRASH.length()).split("/");
} else if (folderPath.startsWith(JUNK)) {
- currentFolderId = DistinguishedFolderId.JUNKEMAIL;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.junkemail);
folderNames = folderPath.substring(JUNK.length()).split("/");
} else if (folderPath.startsWith(UNSENT)) {
- currentFolderId = DistinguishedFolderId.OUTBOX;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.outbox);
folderNames = folderPath.substring(UNSENT.length()).split("/");
} else {
- currentFolderId = DistinguishedFolderId.MSGFOLDERROOT;
+ currentFolderId = DistinguishedFolderId.getInstance(mailbox, DistinguishedFolderId.Name.msgfolderroot);
folderNames = folderPath.split("/");
}
for (String folderName : folderNames) {
@@ -1170,7 +1192,7 @@ public class EwsExchangeSession extends ExchangeSession {
executeMethod(findFolderMethod);
EWSMethod.Item item = findFolderMethod.getResponseItem();
if (item != null) {
- folderId = new FolderId(item);
+ folderId = new FolderId(parentFolderId.mailbox, item);
}
return folderId;
}
diff --git a/src/java/davmail/exchange/ews/FolderId.java b/src/java/davmail/exchange/ews/FolderId.java
index 0771444c..ab88bcc0 100644
--- a/src/java/davmail/exchange/ews/FolderId.java
+++ b/src/java/davmail/exchange/ews/FolderId.java
@@ -26,6 +26,20 @@ import java.io.Writer;
*/
public class FolderId extends Option {
protected String changeKey;
+ protected String mailbox;
+
+ /**
+ * Create FolderId with specified tag name.
+ *
+ * @param name field tag name
+ * @param value id value
+ * @param changeKey folder change key
+ * @param mailbox shared mailbox name
+ */
+ protected FolderId(String name, String value, String changeKey, String mailbox) {
+ this(name, value, changeKey);
+ this.mailbox = mailbox;
+ }
/**
* Create FolderId with specified tag name.
@@ -39,24 +53,14 @@ public class FolderId extends Option {
this.changeKey = changeKey;
}
- /**
- * Create FolderId
- *
- * @param value id value
- * @param changeKey folder change key
- */
- public FolderId(String value, String changeKey) {
- super("t:FolderId", value);
- this.changeKey = changeKey;
- }
-
/**
* Build Folder id from response item.
*
+ * @param mailbox mailbox name
* @param item response item
*/
- public FolderId(EWSMethod.Item item) {
- this(item.get("FolderId"), item.get("ChangeKey"));
+ public FolderId(String mailbox, EWSMethod.Item item) {
+ this("t:FolderId", item.get("FolderId"), item.get("ChangeKey"), mailbox);
}
@@ -73,7 +77,15 @@ public class FolderId extends Option {
writer.write("\" ChangeKey=\"");
writer.write(changeKey);
}
- writer.write("\"/>");
+ if (mailbox == null) {
+ writer.write("\"/>");
+ } else {
+ writer.write("\">");
+ writer.write(mailbox);
+ writer.write("");
+ writer.write(name);
+ writer.write('>');
+ }
}
}
diff --git a/src/java/davmail/exchange/ews/GetUserAvailabilityMethod.java b/src/java/davmail/exchange/ews/GetUserAvailabilityMethod.java
new file mode 100644
index 00000000..5e8a8941
--- /dev/null
+++ b/src/java/davmail/exchange/ews/GetUserAvailabilityMethod.java
@@ -0,0 +1,108 @@
+/*
+ * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
+ * Copyright (C) 2010 Mickael Guessant
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package davmail.exchange.ews;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * GetUserAvailability method.
+ */
+public class GetUserAvailabilityMethod extends EWSMethod {
+ protected String attendee;
+ protected String start;
+ protected String end;
+ protected String mergedFreeBusy;
+ protected int interval;
+
+ /**
+ * Build EWS method
+ *
+ * @param attendee attendee email address
+ * @param start start date in Exchange zulu format
+ * @param end end date in Exchange zulu format
+ * @param interval freebusy interval in minutes
+ */
+ public GetUserAvailabilityMethod(String attendee, String start, String end, int interval) {
+ super("FreeBusy", "GetUserAvailabilityRequest");
+ this.attendee = attendee;
+ this.start = start;
+ this.end = end;
+ this.interval = interval;
+ }
+
+ @Override
+ protected void writeSoapBody(Writer writer) throws IOException {
+ // write UTC timezone
+ writer.write("" +
+ "0" +
+ "" +
+ "0" +
+ "00:00:00" +
+ "1" +
+ "1" +
+ "Sunday" +
+ "" +
+ "" +
+ "0" +
+ "00:00:00" +
+ "1" +
+ "1" +
+ "Sunday" +
+ "" +
+ "");
+ // write attendee address
+ writer.write("" +
+ "" +
+ "" +
+ "");
+ writer.write(attendee);
+ writer.write("" +
+ "" +
+ "Required" +
+ "" +
+ "");
+ // freebusy range
+ writer.write("" +
+ "" +
+ "");
+ writer.write(start);
+ writer.write("" +
+ "");
+ writer.write(end);
+ writer.write("" +
+ "" +
+ "60" +
+ "MergedOnly" +
+ "");
+ }
+
+ @Override
+ protected void handleCustom(XMLStreamReader reader) throws XMLStreamException {
+ if (isStartTag(reader, "MergedFreeBusy")) {
+ this.mergedFreeBusy = reader.getElementText();
+ }
+ }
+
+ public String getMergedFreeBusy() {
+ return mergedFreeBusy;
+ }
+}
diff --git a/src/java/davmail/http/DavGatewayHttpClientFacade.java b/src/java/davmail/http/DavGatewayHttpClientFacade.java
index 7301e163..9934e9f8 100644
--- a/src/java/davmail/http/DavGatewayHttpClientFacade.java
+++ b/src/java/davmail/http/DavGatewayHttpClientFacade.java
@@ -285,6 +285,35 @@ public final class DavGatewayHttpClientFacade {
return currentMethod;
}
+ /**
+ * Execute method with httpClient, do not follow 30x redirects.
+ *
+ * @param httpClient Http client instance
+ * @param method Http method
+ * @return status
+ * @throws IOException on error
+ */
+ public static int executeNoRedirect(HttpClient httpClient, HttpMethod method) throws IOException {
+ int status;
+ try {
+ status = httpClient.executeMethod(method);
+ // check NTLM
+ if ((status == HttpStatus.SC_UNAUTHORIZED || status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
+ && acceptsNTLMOnly(method) && !hasNTLM(httpClient)) {
+ LOGGER.debug("Received " + status + " unauthorized at " + method.getURI() + ", retrying with NTLM");
+ resetMethod(method);
+ addNTLM(httpClient);
+ status = httpClient.executeMethod(method);
+ }
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ method.releaseConnection();
+ }
+ // caller will need to release connection
+ return status;
+ }
+
/**
* Execute webdav search method.
*
diff --git a/src/test/davmail/exchange/TestExchangeSessionCalendar.java b/src/test/davmail/exchange/TestExchangeSessionCalendar.java
index c82d54cf..666154ae 100644
--- a/src/test/davmail/exchange/TestExchangeSessionCalendar.java
+++ b/src/test/davmail/exchange/TestExchangeSessionCalendar.java
@@ -18,18 +18,19 @@
*/
package davmail.exchange;
-import davmail.AbstractDavMailTestCase;
import davmail.Settings;
+import javax.mail.MessagingException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.text.SimpleDateFormat;
import java.util.*;
/**
* Test Exchange session calendar features .
*/
@SuppressWarnings({"UseOfSystemOutOrSystemErr"})
-public class TestExchangeSessionCalendar extends AbstractDavMailTestCase {
+public class TestExchangeSessionCalendar extends AbstractExchangeSessionTestCase {
public void testGetVtimezone() {
ExchangeSession.VTimezone timezone = session.getVTimezone();
@@ -90,5 +91,34 @@ public class TestExchangeSessionCalendar extends AbstractDavMailTestCase {
System.out.println(event.getBody());
}
}
+
+ public void testGetFreeBusyData() throws IOException, MessagingException {
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ cal.set(Calendar.MONTH, 7);
+ cal.set(Calendar.DAY_OF_MONTH, 1);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ Date startDate = cal.getTime();
+ cal.set(Calendar.HOUR_OF_DAY, 23);
+ cal.set(Calendar.MINUTE, 59);
+ cal.set(Calendar.SECOND, 59);
+ Date endDate = cal.getTime();
+ SimpleDateFormat formatter = ExchangeSession.getExchangeZuluDateFormat();
+ // personal fbdata
+ String fbdata = session.getFreeBusyData(session.getEmail(), formatter.format(startDate),
+ formatter.format(endDate), 60);
+ assertNotNull(fbdata);
+ // other user data
+ fbdata = session.getFreeBusyData(Settings.getProperty("davmail.to"), formatter.format(startDate),
+ formatter.format(endDate), 60);
+ assertNotNull(fbdata);
+ // unknown user data
+ fbdata = session.getFreeBusyData("unknown@company.org", formatter.format(startDate),
+ formatter.format(endDate), 60);
+ assertNull(fbdata);
+ }
+
}
+
diff --git a/src/test/davmail/exchange/TestExchangeSessionFolder.java b/src/test/davmail/exchange/TestExchangeSessionFolder.java
index 92a0c158..8668b012 100644
--- a/src/test/davmail/exchange/TestExchangeSessionFolder.java
+++ b/src/test/davmail/exchange/TestExchangeSessionFolder.java
@@ -18,6 +18,9 @@
*/
package davmail.exchange;
+import davmail.Settings;
+
+import javax.mail.MessagingException;
import java.io.IOException;
/**
@@ -121,5 +124,13 @@ public class TestExchangeSessionFolder extends AbstractExchangeSessionTestCase {
session.deleteFolder(folderName);
}
-
+ public void testGetSharedFolder() throws IOException, MessagingException {
+ ExchangeSession.Folder folder = session.getFolder("/users/"+ Settings.getProperty("davmail.to")+"/inbox");
+ ExchangeSession.MessageList messages = session.searchMessages("/users/"+ Settings.getProperty("davmail.to")+"/inbox");
+ for (ExchangeSession.Message message:messages) {
+ System.out.println(message.getMimeMessage());
+ }
+ assertNotNull(folder);
+ }
+
}