EWS: fix 3098008, implement result paging to handle message folders with more than 1000 messages
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1569 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
67e4b676ec
commit
db3f898ce4
|
@ -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<AttributeOption> methodOptions;
|
||||
protected ElementOption unresolvedEntry;
|
||||
|
||||
// paging request
|
||||
protected int maxCount;
|
||||
protected int offset;
|
||||
// paging response
|
||||
protected boolean includesLastItemInRange;
|
||||
|
||||
protected List<FieldUpdate> updates;
|
||||
|
||||
|
@ -368,7 +373,10 @@ public abstract class EWSMethod extends PostMethod {
|
|||
if (maxCount > 0) {
|
||||
writer.write("<m:IndexedPageItemView MaxEntriesReturned=\"");
|
||||
writer.write(String.valueOf(maxCount));
|
||||
writer.write("\" Offset=\"0\" BasePoint=\"Beginning\"/>");
|
||||
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 {
|
||||
|
|
|
@ -50,7 +50,10 @@ import java.util.*;
|
|||
*/
|
||||
public class EwsExchangeSession extends ExchangeSession {
|
||||
|
||||
protected static final int PAGE_SIZE = 100;
|
||||
|
||||
protected static Set<String> MESSAGE_TYPES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
MESSAGE_TYPES.add("Message");
|
||||
MESSAGE_TYPES.add("CalendarItem");
|
||||
|
@ -488,15 +491,26 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||
}
|
||||
|
||||
protected List<EWSMethod.Item> searchItems(String folderPath, Set<String> 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<EWSMethod.Item> results = new ArrayList<EWSMethod.Item>();
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue