diff --git a/src/java/davmail/exchange/ews/EWSMethod.java b/src/java/davmail/exchange/ews/EWSMethod.java index 6fd75203..3e92b082 100644 --- a/src/java/davmail/exchange/ews/EWSMethod.java +++ b/src/java/davmail/exchange/ews/EWSMethod.java @@ -28,7 +28,7 @@ import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.log4j.Logger; -import org.codehaus.stax2.XMLStreamReader2; +import org.codehaus.stax2.typed.TypedXMLStreamReader; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; @@ -55,7 +55,12 @@ public abstract class EWSMethod extends PostMethod { protected Disposal deleteType; protected Set methodOptions; protected ElementOption unresolvedEntry; + + // paging request protected int maxCount; + protected int offset; + // paging response + protected boolean includesLastItemInRange; protected List updates; @@ -368,7 +373,10 @@ public abstract class EWSMethod extends PostMethod { if (maxCount > 0) { writer.write(""); + writer.write("\" Offset=\""); + writer.write(String.valueOf(offset)); + writer.write("\" BasePoint=\"Beginning\"/>"); + } } @@ -838,9 +846,9 @@ public abstract class EWSMethod extends PostMethod { protected void handleMimeContent(XMLStreamReader reader, Item responseItem) throws XMLStreamException { - if (reader instanceof XMLStreamReader2) { + if (reader instanceof TypedXMLStreamReader) { // Stax2 parser: use enhanced base64 conversion - responseItem.mimeContent = ((XMLStreamReader2) reader).getElementAsBinary(); + responseItem.mimeContent = ((TypedXMLStreamReader) reader).getElementAsBinary(); } else { // failover: slow and memory consuming conversion byte[] base64MimeContent = reader.getElementText().getBytes(); @@ -942,6 +950,8 @@ public abstract class EWSMethod extends PostMethod { } else { serverVersion = "Exchange2007_SP1"; } + } else if (XMLStreamUtil.isStartTag(reader, "RootFolder")) { + includesLastItemInRange = "true".equals(reader.getAttributeValue(null, "IncludesLastItemInRange")); } else if (XMLStreamUtil.isStartTag(reader, responseCollectionName)) { handleItems(reader); } else { diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java index c94826fe..f64c31b6 100644 --- a/src/java/davmail/exchange/ews/EwsExchangeSession.java +++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java @@ -50,7 +50,10 @@ import java.util.*; */ public class EwsExchangeSession extends ExchangeSession { + protected static final int PAGE_SIZE = 100; + protected static Set MESSAGE_TYPES = new HashSet(); + static { MESSAGE_TYPES.add("Message"); MESSAGE_TYPES.add("CalendarItem"); @@ -488,15 +491,26 @@ public class EwsExchangeSession extends ExchangeSession { } protected List searchItems(String folderPath, Set attributes, Condition condition, FolderQueryTraversal folderQueryTraversal, int maxCount) throws IOException { - FindItemMethod findItemMethod = new FindItemMethod(folderQueryTraversal, BaseShape.ID_ONLY, getFolderId(folderPath), maxCount); - for (String attribute : attributes) { - findItemMethod.addAdditionalProperty(Field.get(attribute)); - } - if (condition != null && !condition.isEmpty()) { - findItemMethod.setSearchExpression((SearchExpression) condition); - } - executeMethod(findItemMethod); - return findItemMethod.getResponseItems(); + int offset = 0; + List results = new ArrayList(); + FindItemMethod findItemMethod; + do { + int fetchCount = PAGE_SIZE; + if (maxCount > 0) { + fetchCount = Math.min(PAGE_SIZE, maxCount - offset); + } + findItemMethod = new FindItemMethod(folderQueryTraversal, BaseShape.ID_ONLY, getFolderId(folderPath), offset, fetchCount); + for (String attribute : attributes) { + findItemMethod.addAdditionalProperty(Field.get(attribute)); + } + if (condition != null && !condition.isEmpty()) { + findItemMethod.setSearchExpression((SearchExpression) condition); + } + executeMethod(findItemMethod); + results.addAll(findItemMethod.getResponseItems()); + offset = results.size(); + } while (!(findItemMethod.includesLastItemInRange || (maxCount > 0 && offset == maxCount))); + return results; } protected static class MultiCondition extends ExchangeSession.MultiCondition implements SearchExpression { diff --git a/src/java/davmail/exchange/ews/FindItemMethod.java b/src/java/davmail/exchange/ews/FindItemMethod.java index 1a12e28f..033d287b 100644 --- a/src/java/davmail/exchange/ews/FindItemMethod.java +++ b/src/java/davmail/exchange/ews/FindItemMethod.java @@ -28,13 +28,15 @@ public class FindItemMethod extends EWSMethod { * @param traversal folder traversal mode * @param baseShape base item shape * @param parentFolderId parent folder id + * @param offset start offset * @param maxCount maximum result count */ - public FindItemMethod(FolderQueryTraversal traversal, BaseShape baseShape, FolderId parentFolderId, int maxCount) { + public FindItemMethod(FolderQueryTraversal traversal, BaseShape baseShape, FolderId parentFolderId, int offset, int maxCount) { super("Item", "FindItem"); this.traversal = traversal; this.baseShape = baseShape; this.parentFolderId = parentFolderId; + this.offset = offset; this.maxCount = maxCount; } } diff --git a/src/test/davmail/exchange/TestExchangeSessionMessage.java b/src/test/davmail/exchange/TestExchangeSessionMessage.java index 9fea86ec..02e5c2cc 100644 --- a/src/test/davmail/exchange/TestExchangeSessionMessage.java +++ b/src/test/davmail/exchange/TestExchangeSessionMessage.java @@ -42,6 +42,11 @@ public class TestExchangeSessionMessage extends AbstractExchangeSessionTestCase session.createMessage("testfolder", messageName, properties, mimeMessage); } + public void testSearchInbox() throws IOException, MessagingException { + ExchangeSession.MessageList messageList = session.searchMessages("INBOX"); + assertNotNull(messageList); + } + public void testSearchMessage() throws IOException, MessagingException { ExchangeSession.MessageList messageList = session.searchMessages("testfolder"); assertNotNull(messageList);