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("'); + } } } 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); + } + }