1
0
mirror of https://github.com/moparisthebest/davmail synced 2024-12-13 11:12:22 -05:00

ExchangeSession refactoring : remove duplicate code

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@234 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2008-12-17 15:27:56 +00:00
parent 1b71e3ebb5
commit 8bf58be01d
2 changed files with 86 additions and 108 deletions

View File

@ -2,7 +2,6 @@ package davmail.exchange;
import davmail.Settings; import davmail.Settings;
import davmail.http.DavGatewayHttpClientFacade; import davmail.http.DavGatewayHttpClientFacade;
import davmail.tray.DavGatewayTray;
import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.PostMethod;
@ -62,7 +61,6 @@ public class ExchangeSession {
/** /**
* Date parser from Exchange format * Date parser from Exchange format
*/ */
private final SimpleDateFormat dateParser;
private final SimpleDateFormat dateFormatter; private final SimpleDateFormat dateFormatter;
/** /**
@ -82,7 +80,7 @@ public class ExchangeSession {
private String currentFolderUrl; private String currentFolderUrl;
private WebdavResource wdr = null; private WebdavResource wdr = null;
private ExchangeSessionFactory.PoolKey poolKey; private final ExchangeSessionFactory.PoolKey poolKey;
ExchangeSessionFactory.PoolKey getPoolKey() { ExchangeSessionFactory.PoolKey getPoolKey() {
return poolKey; return poolKey;
@ -98,9 +96,6 @@ public class ExchangeSession {
this.poolKey = poolKey; this.poolKey = poolKey;
// SimpleDateFormat are not thread safe, need to create one instance for // SimpleDateFormat are not thread safe, need to create one instance for
// each session // each session
dateParser = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
dateParser.setTimeZone(new SimpleTimeZone(0, "GMT"));
dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
LOGGER.debug("Session " + this + " created"); LOGGER.debug("Session " + this + " created");
} }
@ -158,9 +153,9 @@ public class ExchangeSession {
try { try {
TagNode node = cleaner.clean(initmethod.getResponseBodyAsStream()); TagNode node = cleaner.clean(initmethod.getResponseBodyAsStream());
List<TagNode> forms = (List<TagNode>) node.getElementListByName("form", true); List forms = node.getElementListByName("form", true);
if (forms.size() == 1) { if (forms.size() == 1) {
TagNode form = forms.get(0); TagNode form = (TagNode) forms.get(0);
String logonMethodPath = form.getAttributeByName("action"); String logonMethodPath = form.getAttributeByName("action");
// allow relative URLs // allow relative URLs
@ -173,19 +168,19 @@ public class ExchangeSession {
} }
logonMethod = new PostMethod(logonMethodPath); logonMethod = new PostMethod(logonMethodPath);
List<TagNode> inputList = form.getElementListByName("input", true); List inputList = form.getElementListByName("input", true);
for (TagNode input : inputList) { for (Object input : inputList) {
String type = input.getAttributeByName("type"); String type = ((TagNode) input).getAttributeByName("type");
String name = input.getAttributeByName("name"); String name = ((TagNode) input).getAttributeByName("name");
String value = input.getAttributeByName("value"); String value = ((TagNode) input).getAttributeByName("value");
if ("hidden".equalsIgnoreCase(type) && name != null && value != null) { if ("hidden".equalsIgnoreCase(type) && name != null && value != null) {
logonMethod.addParameter(name, value); logonMethod.addParameter(name, value);
} }
} }
} else { } else {
List<TagNode> frameList = node.getElementListByName("frame", true); List frameList = node.getElementListByName("frame", true);
if (frameList.size() == 1) { if (frameList.size() == 1) {
String src = frameList.get(0).getAttributeByName("src"); String src = ((TagNode) frameList.get(0)).getAttributeByName("src");
if (src != null) { if (src != null) {
LOGGER.debug("Frames detected in form page, try frame content"); LOGGER.debug("Frames detected in form page, try frame content");
initmethod.releaseConnection(); initmethod.releaseConnection();
@ -271,9 +266,6 @@ public class ExchangeSession {
} }
wdr = new WebdavResource(httpURL, WebdavResource.NOACTION, 0); wdr = new WebdavResource(httpURL, WebdavResource.NOACTION, 0);
// set httpclient timeout to 30 seconds
//wdr.retrieveSessionInstance().setTimeout(30000);
// get the internal HttpClient instance // get the internal HttpClient instance
HttpClient httpClient = wdr.retrieveSessionInstance(); HttpClient httpClient = wdr.retrieveSessionInstance();
@ -286,8 +278,6 @@ public class ExchangeSession {
if (!isBasicAuthentication) { if (!isBasicAuthentication) {
method = formLogin(httpClient, method, poolKey.userName, poolKey.password); method = formLogin(httpClient, method, poolKey.userName, poolKey.password);
// reexecute method with new base URL
// method = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, baseUrl);
} }
int status = method.getStatusCode(); int status = method.getStatusCode();
@ -320,11 +310,11 @@ public class ExchangeSession {
wdr.setPath(mailPath); wdr.setPath(mailPath);
getWellKnownFolders(); getWellKnownFolders();
// set current folder to Inbox // set current folder to Inbox
currentFolderUrl = inboxUrl; selectFolder("INBOX");
wdr.setPath(URIUtil.getPath(inboxUrl)); wdr.setPath(URIUtil.getPath(inboxUrl));
} catch (Exception exc) { } catch (IOException exc) {
StringBuffer message = new StringBuffer(); StringBuffer message = new StringBuffer();
message.append("DavMail login exception: "); message.append("DavMail login exception: ");
if (exc.getMessage() != null) { if (exc.getMessage() != null) {
@ -496,34 +486,17 @@ public class ExchangeSession {
public List<Message> getAllMessages() throws IOException { public List<Message> getAllMessages() throws IOException {
List<Message> messages = new ArrayList<Message>(); List<Message> messages = new ArrayList<Message>();
String searchRequest = "<?xml version=\"1.0\"?>\n" + String searchRequest = "Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
"<d:searchrequest xmlns:d=\"DAV:\">\n" +
" <d:sql>Select \"DAV:uid\", \"http://schemas.microsoft.com/mapi/proptag/x0e080003\"" +
" FROM Scope('SHALLOW TRAVERSAL OF \"" + currentFolderUrl + "\"')\n" + " FROM Scope('SHALLOW TRAVERSAL OF \"" + currentFolderUrl + "\"')\n" +
" WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" + " WHERE \"DAV:ishidden\" = False AND \"DAV:isfolder\" = False\n" +
" ORDER BY \"urn:schemas:httpmail:date\" ASC" + " ORDER BY \"urn:schemas:httpmail:date\" ASC";
" </d:sql>\n" + Enumeration folderEnum = DavGatewayHttpClientFacade.executeSearchMethod(wdr.retrieveSessionInstance(), currentFolderUrl, searchRequest);
"</d:searchrequest>";
SearchMethod searchMethod = new SearchMethod(URIUtil.encodePath(currentFolderUrl), searchRequest);
try {
int status = wdr.retrieveSessionInstance().executeMethod(searchMethod);
// Also accept OK sent by buggy servers.
if (status != HttpStatus.SC_MULTI_STATUS
&& status != HttpStatus.SC_OK) {
HttpException ex = new HttpException();
ex.setReasonCode(status);
throw ex;
}
Enumeration folderEnum = searchMethod.getResponses();
while (folderEnum.hasMoreElements()) { while (folderEnum.hasMoreElements()) {
ResponseEntity entity = (ResponseEntity) folderEnum.nextElement(); ResponseEntity entity = (ResponseEntity) folderEnum.nextElement();
Message message = buildMessage(entity); Message message = buildMessage(entity);
messages.add(message); messages.add(message);
}
} finally {
searchMethod.releaseConnection();
} }
return messages; return messages;
} }
@ -551,37 +524,18 @@ public class ExchangeSession {
cal.add(Calendar.DAY_OF_MONTH, -keepDelay); cal.add(Calendar.DAY_OF_MONTH, -keepDelay);
LOGGER.debug("Delete messages in " + folderUrl + " since " + cal.getTime()); LOGGER.debug("Delete messages in " + folderUrl + " since " + cal.getTime());
String searchRequest = "<?xml version=\"1.0\"?>\n" + String searchRequest = "Select \"DAV:uid\"" +
"<d:searchrequest xmlns:d=\"DAV:\">\n" +
" <d:sql>Select \"DAV:uid\"" +
" FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" + " FROM Scope('SHALLOW TRAVERSAL OF \"" + folderUrl + "\"')\n" +
" WHERE \"DAV:isfolder\" = False\n" + " WHERE \"DAV:isfolder\" = False\n" +
" AND \"DAV:getlastmodified\" &lt; '" + dateFormatter.format(cal.getTime()) + "'\n" + " AND \"DAV:getlastmodified\" &lt; '" + dateFormatter.format(cal.getTime()) + "'\n";
" </d:sql>\n" + Enumeration folderEnum = DavGatewayHttpClientFacade.executeSearchMethod(wdr.retrieveSessionInstance(), folderUrl, searchRequest);
"</d:searchrequest>";
SearchMethod searchMethod = new SearchMethod(URIUtil.encodePath(currentFolderUrl), searchRequest);
//searchMethod.setDebug(4);
try {
int status = wdr.retrieveSessionInstance().executeMethod(searchMethod);
// Also accept OK sent by buggy servers.
if (status != HttpStatus.SC_MULTI_STATUS
&& status != HttpStatus.SC_OK) {
HttpException ex = new HttpException();
ex.setReasonCode(status);
throw ex;
}
Enumeration folderEnum = searchMethod.getResponses(); while (folderEnum.hasMoreElements()) {
ResponseEntity entity = (ResponseEntity) folderEnum.nextElement();
String messageUrl = URIUtil.decode(entity.getHref());
while (folderEnum.hasMoreElements()) { LOGGER.debug("Delete " + messageUrl);
ResponseEntity entity = (ResponseEntity) folderEnum.nextElement(); wdr.deleteMethod(messageUrl);
String messageUrl = URIUtil.decode(entity.getHref());
LOGGER.debug("Delete " + messageUrl);
wdr.deleteMethod(messageUrl);
}
} finally {
searchMethod.releaseConnection();
} }
} }
@ -593,8 +547,7 @@ public class ExchangeSession {
boolean inHeader = true; boolean inHeader = true;
boolean inRecipientHeader = false; boolean inRecipientHeader = false;
while (!".".equals(line)) { while (!".".equals(line)) {
mailBuffer.append(line); mailBuffer.append(line).append("\n");
mailBuffer.append("\n");
line = reader.readLine(); line = reader.readLine();
if (inHeader && line.length() == 0) { if (inHeader && line.length() == 0) {
@ -612,7 +565,8 @@ public class ExchangeSession {
} }
// patch thunderbird html in reply for correct outlook display // patch thunderbird html in reply for correct outlook display
if (line.startsWith("<head>")) { if (line.startsWith("<head>")) {
line += "\n <style> blockquote { display: block; margin: 1em 0px; padding-left: 1em; border-left: solid; border-color: blue; border-width: thin;}</style>"; mailBuffer.append(line).append("\n");
line = " <style> blockquote { display: block; margin: 1em 0px; padding-left: 1em; border-left: solid; border-color: blue; border-width: thin;}</style>";
} else if (line.startsWith("Subject")) { } else if (line.startsWith("Subject")) {
subject = MimeUtility.decodeText(line.substring(8).trim()); subject = MimeUtility.decodeText(line.substring(8).trim());
// '/' is invalid as message URL // '/' is invalid as message URL
@ -793,7 +747,7 @@ public class ExchangeSession {
} }
public WebdavResource getWebDavResource() throws IOException { public WebdavResource getWebDavResource() {
return wdr; return wdr;
} }
@ -802,7 +756,7 @@ public class ExchangeSession {
protected String etag; protected String etag;
public String getICS() throws IOException { public String getICS() throws IOException {
DavGatewayTray.debug("Get event: " + href); LOGGER.debug("Get event: " + href);
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
GetMethod method = new GetMethod(URIUtil.encodePath(href)); GetMethod method = new GetMethod(URIUtil.encodePath(href));
method.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); method.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
@ -811,7 +765,7 @@ public class ExchangeSession {
try { try {
int status = wdr.retrieveSessionInstance().executeMethod(method); int status = wdr.retrieveSessionInstance().executeMethod(method);
if (status != HttpStatus.SC_OK) { if (status != HttpStatus.SC_OK) {
DavGatewayTray.warn("Unable to get event at " + href + " status: " + status); LOGGER.warn("Unable to get event at " + href + " status: " + status);
} }
eventReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8")); eventReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
String line; String line;
@ -843,7 +797,7 @@ public class ExchangeSession {
return fixICS(buffer.toString(), true); return fixICS(buffer.toString(), true);
} }
public String getPath() throws URIException { public String getPath() {
return href.substring(calendarUrl.length()); return href.substring(calendarUrl.length());
} }
@ -887,19 +841,7 @@ public class ExchangeSession {
Enumeration calendarEnum = searchMethod.getResponses(); Enumeration calendarEnum = searchMethod.getResponses();
while (calendarEnum.hasMoreElements()) { while (calendarEnum.hasMoreElements()) {
ResponseEntity calendarResponse = (ResponseEntity) calendarEnum. events.add(buildEvent((ResponseEntity) calendarEnum.nextElement()));
nextElement();
String href = calendarResponse.getHref();
Event event = new Event();
event.href = URIUtil.decode(href);
Enumeration propertiesEnumeration = calendarResponse.getProperties();
while (propertiesEnumeration.hasMoreElements()) {
Property property = (Property) propertiesEnumeration.nextElement();
if ("getetag".equals(property.getLocalName())) {
event.etag = property.getPropertyAsString();
}
}
events.add(event);
} }
} finally { } finally {
searchMethod.releaseConnection(); searchMethod.releaseConnection();
@ -908,17 +850,16 @@ public class ExchangeSession {
} }
public Event getEvent(String path) throws IOException { public Event getEvent(String path) throws IOException {
// TODO : refactor with getAllEvents
Event event = new Event();
//wdr.setDebug(4);
Enumeration calendarEnum = wdr.propfindMethod(calendarUrl + "/" + URIUtil.decode(path), 0, EVENT_REQUEST_PROPERTIES); Enumeration calendarEnum = wdr.propfindMethod(calendarUrl + "/" + URIUtil.decode(path), 0, EVENT_REQUEST_PROPERTIES);
//wdr.setDebug(0);
if (!calendarEnum.hasMoreElements()) { if (!calendarEnum.hasMoreElements()) {
throw new IOException("Unable to get calendar event"); throw new IOException("Unable to get calendar event");
} }
ResponseEntity calendarResponse = (ResponseEntity) calendarEnum. return buildEvent((ResponseEntity) calendarEnum.
nextElement(); nextElement());
}
protected Event buildEvent(ResponseEntity calendarResponse) throws URIException {
Event event = new Event();
String href = calendarResponse.getHref(); String href = calendarResponse.getHref();
event.href = URIUtil.decode(href); event.href = URIUtil.decode(href);
Enumeration propertiesEnumeration = calendarResponse.getProperties(); Enumeration propertiesEnumeration = calendarResponse.getProperties();
@ -934,9 +875,9 @@ public class ExchangeSession {
protected String fixICS(String icsBody, boolean fromServer) throws IOException { protected String fixICS(String icsBody, boolean fromServer) throws IOException {
// first pass : detect // first pass : detect
class AllDayState { class AllDayState {
boolean isAllDay = false; boolean isAllDay = false;
boolean hasCdoAllDay = false; boolean hasCdoAllDay = false;
boolean isCdoAllDay = false; boolean isCdoAllDay = false;
} }
List<AllDayState> allDayStates = new ArrayList<AllDayState>(); List<AllDayState> allDayStates = new ArrayList<AllDayState>();
AllDayState currentAllDayState = new AllDayState(); AllDayState currentAllDayState = new AllDayState();
@ -998,7 +939,7 @@ public class ExchangeSession {
int keyIndex = line.indexOf(';'); int keyIndex = line.indexOf(';');
int valueIndex = line.lastIndexOf(':'); int valueIndex = line.lastIndexOf(':');
int valueEndIndex = line.lastIndexOf('T'); int valueEndIndex = line.lastIndexOf('T');
if (keyIndex < 0 || valueIndex < 0|| valueEndIndex < 0) { if (keyIndex < 0 || valueIndex < 0 || valueEndIndex < 0) {
throw new IOException("Invalid ICS line: " + line); throw new IOException("Invalid ICS line: " + line);
} }
String dateValue = line.substring(valueIndex + 1); String dateValue = line.substring(valueIndex + 1);
@ -1014,7 +955,7 @@ public class ExchangeSession {
if ("DTEND".equals(key)) { if ("DTEND".equals(key)) {
date.setTime(date.getTime() - 1); date.setTime(date.getTime() - 1);
} }
return line.substring(0, keyIndex) + ";VALUE=DATE:" + line.substring(valueIndex+1, valueEndIndex); return line.substring(0, keyIndex) + ";VALUE=DATE:" + line.substring(valueIndex + 1, valueEndIndex);
} }
public int createOrUpdateEvent(String path, String icsBody, String etag) throws IOException { public int createOrUpdateEvent(String path, String icsBody, String etag) throws IOException {
@ -1231,7 +1172,6 @@ public class ExchangeSession {
if (status != HttpStatus.SC_OK) { if (status != HttpStatus.SC_OK) {
throw new IOException("Unable to get free-busy from: " + getMethod.getPath()); throw new IOException("Unable to get free-busy from: " + getMethod.getPath());
} }
// TODO : parse
String body = getMethod.getResponseBodyAsString(); String body = getMethod.getResponseBodyAsString();
int startIndex = body.lastIndexOf("<a:fbdata>"); int startIndex = body.lastIndexOf("<a:fbdata>");
int endIndex = body.lastIndexOf("</a:fbdata>"); int endIndex = body.lastIndexOf("</a:fbdata>");
@ -1265,7 +1205,7 @@ public class ExchangeSession {
getMethod.releaseConnection(); getMethod.releaseConnection();
} }
if (result == null) { if (result == null) {
throw new IOException("Unable to get user email from: " + getMethod.getPath()); throw new IOException("Unable to get user free-busy data from: " + getMethod.getPath());
} }
return result; return result;

View File

@ -3,14 +3,20 @@ package davmail.http;
import davmail.Settings; import davmail.Settings;
import davmail.tray.DavGatewayTray; import davmail.tray.DavGatewayTray;
import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.webdav.lib.methods.SearchMethod;
import org.apache.webdav.lib.ResponseEntity;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Enumeration;
/** /**
* Create HttpClient instance according to DavGateway Settings * Create HttpClient instance according to DavGateway Settings
*/ */
public class DavGatewayHttpClientFacade { public final class DavGatewayHttpClientFacade {
static MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager; static MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager;
static { static {
@ -155,6 +161,38 @@ public class DavGatewayHttpClientFacade {
return method; return method;
} }
/**
* Execute webdav search method
* @param httpClient http client instance
* @param folderUrl searched folder
* @param searchRequest (SQL like) search request
* @return Responses
* @throws IOException on error
*/
public static Enumeration executeSearchMethod(HttpClient httpClient, String folderUrl, String searchRequest) throws IOException {
Enumeration folderEnum = null;
String searchBody = "<?xml version=\"1.0\"?>\n" +
"<d:searchrequest xmlns:d=\"DAV:\">\n" +
" <d:sql>" + searchRequest + "</d:sql>\n" +
"</d:searchrequest>";
SearchMethod searchMethod = new SearchMethod(URIUtil.encodePath(folderUrl), searchBody);
try {
int status = httpClient.executeMethod(searchMethod);
// Also accept OK sent by buggy servers.
if (status != HttpStatus.SC_MULTI_STATUS
&& status != HttpStatus.SC_OK) {
HttpException ex = new HttpException();
ex.setReasonCode(status);
throw ex;
}
folderEnum = searchMethod.getResponses();
} finally {
searchMethod.releaseConnection();
}
return folderEnum;
}
public static void stop() { public static void stop() {
if (multiThreadedHttpConnectionManager != null) { if (multiThreadedHttpConnectionManager != null) {
multiThreadedHttpConnectionManager.shutdown(); multiThreadedHttpConnectionManager.shutdown();