mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-14 11:42:23 -05:00
EWS: refactor folder search, create abstract getFolder methods
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1076 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
6ed44eedf6
commit
20c466059a
@ -846,67 +846,7 @@ public abstract class ExchangeSession {
|
|||||||
* @return list of folders
|
* @return list of folders
|
||||||
* @throws IOException on error
|
* @throws IOException on error
|
||||||
*/
|
*/
|
||||||
public List<Folder> getSubFolders(String folderName, String filter, boolean recursive) throws IOException {
|
public abstract List<Folder> getSubFolders(String folderName, String filter, boolean recursive) throws IOException;
|
||||||
String mode = recursive ? "DEEP" : "SHALLOW";
|
|
||||||
List<Folder> folders = new ArrayList<Folder>();
|
|
||||||
StringBuilder searchRequest = new StringBuilder();
|
|
||||||
searchRequest.append("Select \"DAV:nosubs\", \"DAV:hassubs\", \"DAV:hassubs\"," +
|
|
||||||
"\"urn:schemas:httpmail:unreadcount\" FROM Scope('").append(mode).append(" TRAVERSAL OF \"").append(getFolderPath(folderName)).append("\"')\n" +
|
|
||||||
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = True \n");
|
|
||||||
if (filter != null && filter.length() > 0) {
|
|
||||||
searchRequest.append(" AND ").append(filter);
|
|
||||||
}
|
|
||||||
MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executeSearchMethod(
|
|
||||||
httpClient, URIUtil.encodePath(getFolderPath(folderName)), searchRequest.toString());
|
|
||||||
|
|
||||||
for (MultiStatusResponse response : responses) {
|
|
||||||
folders.add(buildFolder(response));
|
|
||||||
}
|
|
||||||
return folders;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Folder buildFolder(MultiStatusResponse entity) throws IOException {
|
|
||||||
String href = URIUtil.decode(entity.getHref());
|
|
||||||
Folder folder = new Folder();
|
|
||||||
DavPropertySet properties = entity.getProperties(HttpStatus.SC_OK);
|
|
||||||
folder.contentClass = getPropertyIfExists(properties, "contentclass", DAV);
|
|
||||||
folder.hasChildren = "1".equals(getPropertyIfExists(properties, "hassubs", DAV));
|
|
||||||
folder.noInferiors = "1".equals(getPropertyIfExists(properties, "nosubs", DAV));
|
|
||||||
folder.unreadCount = getIntPropertyIfExists(properties, "unreadcount", URN_SCHEMAS_HTTPMAIL);
|
|
||||||
folder.ctag = getPropertyIfExists(properties, "contenttag", Namespace.getNamespace("http://schemas.microsoft.com/repl/"));
|
|
||||||
folder.etag = getPropertyIfExists(properties, "resourcetag", Namespace.getNamespace("http://schemas.microsoft.com/repl/"));
|
|
||||||
|
|
||||||
// replace well known folder names
|
|
||||||
if (href.startsWith(inboxUrl)) {
|
|
||||||
folder.folderPath = href.replaceFirst(inboxUrl, "INBOX");
|
|
||||||
} else if (href.startsWith(sentitemsUrl)) {
|
|
||||||
folder.folderPath = href.replaceFirst(sentitemsUrl, "Sent");
|
|
||||||
} else if (href.startsWith(draftsUrl)) {
|
|
||||||
folder.folderPath = href.replaceFirst(draftsUrl, "Drafts");
|
|
||||||
} else if (href.startsWith(deleteditemsUrl)) {
|
|
||||||
folder.folderPath = href.replaceFirst(deleteditemsUrl, "Trash");
|
|
||||||
} else {
|
|
||||||
int index = href.indexOf(mailPath.substring(0, mailPath.length() - 1));
|
|
||||||
if (index >= 0) {
|
|
||||||
if (index + mailPath.length() > href.length()) {
|
|
||||||
folder.folderPath = "";
|
|
||||||
} else {
|
|
||||||
folder.folderPath = href.substring(index + mailPath.length());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
URI folderURI = new URI(href, false);
|
|
||||||
folder.folderPath = folderURI.getPath();
|
|
||||||
} catch (URIException e) {
|
|
||||||
throw new DavMailException("EXCEPTION_INVALID_FOLDER_URL", href);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (folder.folderPath.endsWith("/")) {
|
|
||||||
folder.folderPath = folder.folderPath.substring(0, folder.folderPath.length() - 1);
|
|
||||||
}
|
|
||||||
return folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete oldest messages in trash.
|
* Delete oldest messages in trash.
|
||||||
@ -1062,16 +1002,7 @@ public abstract class ExchangeSession {
|
|||||||
* @return Folder object
|
* @return Folder object
|
||||||
* @throws IOException on error
|
* @throws IOException on error
|
||||||
*/
|
*/
|
||||||
public Folder getFolder(String folderName) throws IOException {
|
public abstract Folder getFolder(String folderName) throws IOException;
|
||||||
MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executePropFindMethod(
|
|
||||||
httpClient, URIUtil.encodePath(getFolderPath(folderName)), 0, FOLDER_PROPERTIES);
|
|
||||||
Folder folder = null;
|
|
||||||
if (responses.length > 0) {
|
|
||||||
folder = buildFolder(responses[0]);
|
|
||||||
folder.folderName = folderName;
|
|
||||||
}
|
|
||||||
return folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check folder ctag and reload messages as needed.
|
* Check folder ctag and reload messages as needed.
|
||||||
|
@ -25,15 +25,19 @@ import davmail.http.DavGatewayHttpClientFacade;
|
|||||||
import org.apache.commons.httpclient.HttpMethod;
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
import org.apache.commons.httpclient.URI;
|
import org.apache.commons.httpclient.URI;
|
||||||
|
import org.apache.commons.httpclient.URIException;
|
||||||
import org.apache.commons.httpclient.util.URIUtil;
|
import org.apache.commons.httpclient.util.URIUtil;
|
||||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
||||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
|
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
|
||||||
import org.apache.jackrabbit.webdav.property.DavPropertySet;
|
import org.apache.jackrabbit.webdav.property.DavPropertySet;
|
||||||
|
import org.apache.jackrabbit.webdav.xml.Namespace;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Webdav Exchange adapter.
|
* Webdav Exchange adapter.
|
||||||
@ -164,4 +168,85 @@ public class DavExchangeSession extends ExchangeSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Folder buildFolder(MultiStatusResponse entity) throws IOException {
|
||||||
|
String href = URIUtil.decode(entity.getHref());
|
||||||
|
Folder folder = new Folder();
|
||||||
|
DavPropertySet properties = entity.getProperties(HttpStatus.SC_OK);
|
||||||
|
folder.contentClass = getPropertyIfExists(properties, "contentclass", DAV);
|
||||||
|
folder.hasChildren = "1".equals(getPropertyIfExists(properties, "hassubs", DAV));
|
||||||
|
folder.noInferiors = "1".equals(getPropertyIfExists(properties, "nosubs", DAV));
|
||||||
|
folder.unreadCount = getIntPropertyIfExists(properties, "unreadcount", URN_SCHEMAS_HTTPMAIL);
|
||||||
|
folder.ctag = getPropertyIfExists(properties, "contenttag", Namespace.getNamespace("http://schemas.microsoft.com/repl/"));
|
||||||
|
folder.etag = getPropertyIfExists(properties, "resourcetag", Namespace.getNamespace("http://schemas.microsoft.com/repl/"));
|
||||||
|
|
||||||
|
// replace well known folder names
|
||||||
|
if (href.startsWith(inboxUrl)) {
|
||||||
|
folder.folderPath = href.replaceFirst(inboxUrl, "INBOX");
|
||||||
|
} else if (href.startsWith(sentitemsUrl)) {
|
||||||
|
folder.folderPath = href.replaceFirst(sentitemsUrl, "Sent");
|
||||||
|
} else if (href.startsWith(draftsUrl)) {
|
||||||
|
folder.folderPath = href.replaceFirst(draftsUrl, "Drafts");
|
||||||
|
} else if (href.startsWith(deleteditemsUrl)) {
|
||||||
|
folder.folderPath = href.replaceFirst(deleteditemsUrl, "Trash");
|
||||||
|
} else {
|
||||||
|
int index = href.indexOf(mailPath.substring(0, mailPath.length() - 1));
|
||||||
|
if (index >= 0) {
|
||||||
|
if (index + mailPath.length() > href.length()) {
|
||||||
|
folder.folderPath = "";
|
||||||
|
} else {
|
||||||
|
folder.folderPath = href.substring(index + mailPath.length());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
URI folderURI = new URI(href, false);
|
||||||
|
folder.folderPath = folderURI.getPath();
|
||||||
|
} catch (URIException e) {
|
||||||
|
throw new DavMailException("EXCEPTION_INVALID_FOLDER_URL", href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (folder.folderPath.endsWith("/")) {
|
||||||
|
folder.folderPath = folder.folderPath.substring(0, folder.folderPath.length() - 1);
|
||||||
|
}
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Folder getFolder(String folderName) throws IOException {
|
||||||
|
MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executePropFindMethod(
|
||||||
|
httpClient, URIUtil.encodePath(getFolderPath(folderName)), 0, FOLDER_PROPERTIES);
|
||||||
|
Folder folder = null;
|
||||||
|
if (responses.length > 0) {
|
||||||
|
folder = buildFolder(responses[0]);
|
||||||
|
folder.folderName = folderName;
|
||||||
|
}
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Folder> getSubFolders(String folderName, String filter, boolean recursive) throws IOException {
|
||||||
|
String mode = recursive ? "DEEP" : "SHALLOW";
|
||||||
|
List<Folder> folders = new ArrayList<Folder>();
|
||||||
|
StringBuilder searchRequest = new StringBuilder();
|
||||||
|
searchRequest.append("Select \"DAV:nosubs\", \"DAV:hassubs\"," +
|
||||||
|
"\"urn:schemas:httpmail:unreadcount\" FROM Scope('").append(mode).append(" TRAVERSAL OF \"").append(getFolderPath(folderName)).append("\"')\n" +
|
||||||
|
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = True \n");
|
||||||
|
if (filter != null && filter.length() > 0) {
|
||||||
|
searchRequest.append(" AND ").append(filter);
|
||||||
|
}
|
||||||
|
MultiStatusResponse[] responses = DavGatewayHttpClientFacade.executeSearchMethod(
|
||||||
|
httpClient, URIUtil.encodePath(getFolderPath(folderName)), searchRequest.toString());
|
||||||
|
|
||||||
|
for (MultiStatusResponse response : responses) {
|
||||||
|
folders.add(buildFolder(response));
|
||||||
|
}
|
||||||
|
return folders;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import davmail.exchange.ExchangeSession;
|
|||||||
import org.apache.commons.httpclient.HttpMethod;
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EWS Exchange adapter.
|
* EWS Exchange adapter.
|
||||||
@ -30,6 +31,10 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class EwsExchangeSession extends ExchangeSession {
|
public class EwsExchangeSession extends ExchangeSession {
|
||||||
|
|
||||||
|
protected class EwsFolder extends Folder {
|
||||||
|
public FolderId folderId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@ -42,4 +47,72 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||||||
// nothing to do, mailPath not used in EWS mode
|
// nothing to do, mailPath not used in EWS mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Folder> getSubFolders(String folderName, String filter, boolean recursive) throws IOException {
|
||||||
|
// TODO
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Folder getFolder(String folderPath) throws IOException {
|
||||||
|
GetFolderMethod getFolderMethod = new GetFolderMethod(BaseShape.ALL_PROPERTIES, getFolderId(folderPath));
|
||||||
|
getFolderMethod.addAdditionalProperty(ExtendedFieldURI.PR_URL_COMP_NAME);
|
||||||
|
getFolderMethod.addAdditionalProperty(ExtendedFieldURI.PR_LAST_MODIFICATION_TIME);
|
||||||
|
//getFolderMethod.addAdditionalProperty(new ExtendedFieldURI("0x65E2", ExtendedFieldURI.PropertyType.Binary));
|
||||||
|
//getFolderMethod.addAdditionalProperty(new ExtendedFieldURI("00062040-0000-0000-C000-000000000046", 0x8A23, ExtendedFieldURI.PropertyType.SystemTime));
|
||||||
|
|
||||||
|
httpClient.executeMethod(getFolderMethod);
|
||||||
|
EWSMethod.Item item = getFolderMethod.getResponseItem();
|
||||||
|
EwsFolder folder = null;
|
||||||
|
if (item != null) {
|
||||||
|
folder = new EwsFolder();
|
||||||
|
folder.folderId = new FolderId(item.get("FolderId"));
|
||||||
|
folder.folderName = folderPath;
|
||||||
|
folder.etag = item.get(ExtendedFieldURI.PR_LAST_MODIFICATION_TIME.getPropertyTag());
|
||||||
|
// TODO: implement ctag
|
||||||
|
folder.ctag = String.valueOf(System.currentTimeMillis());
|
||||||
|
// TODO: implement contentClass, unreadCount, hasChildren, noInferiors
|
||||||
|
}
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private FolderId getFolderId(String folderPath) throws IOException {
|
||||||
|
FolderId currentFolderId = DistinguishedFolderId.MSGFOLDERROOT;
|
||||||
|
String[] folderNames = folderPath.split("/");
|
||||||
|
for (String folderName : folderNames) {
|
||||||
|
if ("INBOX".equals(folderName)) {
|
||||||
|
currentFolderId = DistinguishedFolderId.INBOX;
|
||||||
|
} else if ("Sent".equals(folderName)) {
|
||||||
|
currentFolderId = DistinguishedFolderId.SENTITEMS;
|
||||||
|
} else if ("Drafts".equals(folderName)) {
|
||||||
|
currentFolderId = DistinguishedFolderId.DRAFTS;
|
||||||
|
} else if ("Trash".equals(folderName)) {
|
||||||
|
currentFolderId = DistinguishedFolderId.DELETEDITEMS;
|
||||||
|
} else {
|
||||||
|
currentFolderId = getSubFolderByName(currentFolderId, folderName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentFolderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FolderId getSubFolderByName(FolderId parentFolderId, String folderName) throws IOException {
|
||||||
|
FindFolderMethod findFolderMethod = new FindFolderMethod(
|
||||||
|
FolderQueryTraversal.SHALLOW,
|
||||||
|
BaseShape.ID_ONLY,
|
||||||
|
parentFolderId,
|
||||||
|
new TwoOperandExpression(TwoOperandExpression.Operator.IsEqualTo,
|
||||||
|
ExtendedFieldURI.PR_URL_COMP_NAME, folderName)
|
||||||
|
);
|
||||||
|
httpClient.executeMethod(findFolderMethod);
|
||||||
|
EWSMethod.Item item = findFolderMethod.getResponseItem();
|
||||||
|
return new FolderId(item.get("Id"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,13 @@ package davmail.exchange.ews;
|
|||||||
*/
|
*/
|
||||||
public class FindFolderMethod extends EWSMethod {
|
public class FindFolderMethod extends EWSMethod {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Exchange Folder.
|
||||||
|
*
|
||||||
|
* @param traversal traversal type
|
||||||
|
* @param baseShape base shape
|
||||||
|
* @param parentFolderId parent folder id
|
||||||
|
*/
|
||||||
public FindFolderMethod(FolderQueryTraversal traversal, BaseShape baseShape, FolderId parentFolderId) {
|
public FindFolderMethod(FolderQueryTraversal traversal, BaseShape baseShape, FolderId parentFolderId) {
|
||||||
super("Folder", "FindFolder");
|
super("Folder", "FindFolder");
|
||||||
this.traversal = traversal;
|
this.traversal = traversal;
|
||||||
@ -30,4 +37,17 @@ public class FindFolderMethod extends EWSMethod {
|
|||||||
this.parentFolderId = parentFolderId;
|
this.parentFolderId = parentFolderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Exchange Folder.
|
||||||
|
*
|
||||||
|
* @param traversal traversal type
|
||||||
|
* @param baseShape base shape
|
||||||
|
* @param parentFolderId parent folder id
|
||||||
|
* @param searchExpression search expression
|
||||||
|
*/
|
||||||
|
public FindFolderMethod(FolderQueryTraversal traversal, BaseShape baseShape, FolderId parentFolderId,
|
||||||
|
SearchExpression searchExpression) {
|
||||||
|
this(traversal, baseShape, parentFolderId);
|
||||||
|
this.searchExpression = searchExpression;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user