2010-05-18 07:50:00 -04:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2010-07-27 15:26:54 -04:00
|
|
|
import davmail.exchange.XMLStreamUtil;
|
2010-07-25 08:58:25 -04:00
|
|
|
import davmail.util.StringUtil;
|
2010-05-20 09:07:00 -04:00
|
|
|
import org.apache.commons.codec.binary.Base64;
|
2010-05-18 07:50:00 -04:00
|
|
|
import org.apache.commons.httpclient.Header;
|
|
|
|
import org.apache.commons.httpclient.HttpConnection;
|
|
|
|
import org.apache.commons.httpclient.HttpState;
|
2010-07-21 12:42:46 -04:00
|
|
|
import org.apache.commons.httpclient.HttpStatus;
|
2010-05-18 07:50:00 -04:00
|
|
|
import org.apache.commons.httpclient.methods.PostMethod;
|
|
|
|
import org.apache.commons.httpclient.methods.RequestEntity;
|
|
|
|
import org.apache.log4j.Logger;
|
2010-12-08 16:39:55 -05:00
|
|
|
import org.codehaus.stax2.typed.TypedXMLStreamReader;
|
2010-05-18 07:50:00 -04:00
|
|
|
|
|
|
|
import javax.xml.stream.XMLStreamConstants;
|
|
|
|
import javax.xml.stream.XMLStreamException;
|
|
|
|
import javax.xml.stream.XMLStreamReader;
|
|
|
|
import java.io.*;
|
2010-05-21 04:44:43 -04:00
|
|
|
import java.util.*;
|
2010-05-18 07:50:00 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* EWS SOAP method.
|
|
|
|
*/
|
|
|
|
public abstract class EWSMethod extends PostMethod {
|
2010-12-17 08:06:11 -05:00
|
|
|
protected static final Logger LOGGER = Logger.getLogger(EWSMethod.class);
|
2010-05-18 07:50:00 -04:00
|
|
|
|
2010-05-21 04:44:43 -04:00
|
|
|
protected FolderQueryTraversal traversal;
|
|
|
|
protected BaseShape baseShape;
|
2010-05-20 05:22:03 -04:00
|
|
|
protected boolean includeMimeContent;
|
2010-05-21 04:44:43 -04:00
|
|
|
protected FolderId folderId;
|
2010-07-05 05:58:18 -04:00
|
|
|
protected FolderId savedItemFolderId;
|
2010-06-29 10:15:50 -04:00
|
|
|
protected FolderId toFolderId;
|
2010-05-21 04:44:43 -04:00
|
|
|
protected FolderId parentFolderId;
|
|
|
|
protected ItemId itemId;
|
2010-07-17 06:45:21 -04:00
|
|
|
protected ItemId parentItemId;
|
2010-06-10 16:47:55 -04:00
|
|
|
protected Set<FieldURI> additionalProperties;
|
2010-05-21 04:44:43 -04:00
|
|
|
protected Disposal deleteType;
|
2010-07-05 09:48:43 -04:00
|
|
|
protected Set<AttributeOption> methodOptions;
|
2010-07-27 15:26:54 -04:00
|
|
|
protected ElementOption unresolvedEntry;
|
2010-12-08 16:39:55 -05:00
|
|
|
|
|
|
|
// paging request
|
2010-07-27 16:34:43 -04:00
|
|
|
protected int maxCount;
|
2010-12-08 16:39:55 -05:00
|
|
|
protected int offset;
|
|
|
|
// paging response
|
|
|
|
protected boolean includesLastItemInRange;
|
2010-05-20 05:22:03 -04:00
|
|
|
|
2010-09-15 18:49:19 -04:00
|
|
|
protected List<FieldUpdate> updates;
|
2010-06-29 10:15:50 -04:00
|
|
|
|
2010-07-17 06:45:21 -04:00
|
|
|
protected FileAttachment attachment;
|
|
|
|
|
|
|
|
protected String attachmentId;
|
|
|
|
|
2010-05-20 05:22:03 -04:00
|
|
|
protected final String itemType;
|
|
|
|
protected final String methodName;
|
|
|
|
protected final String responseCollectionName;
|
2010-05-18 07:50:00 -04:00
|
|
|
|
2010-05-20 09:07:00 -04:00
|
|
|
protected List<Item> responseItems;
|
|
|
|
protected String errorDetail;
|
2010-05-21 04:44:43 -04:00
|
|
|
protected Item item;
|
2010-05-18 07:50:00 -04:00
|
|
|
|
2010-05-26 17:40:08 -04:00
|
|
|
protected SearchExpression searchExpression;
|
|
|
|
|
2010-07-27 08:58:23 -04:00
|
|
|
protected String serverVersion;
|
2010-05-26 17:40:08 -04:00
|
|
|
|
2010-05-18 07:50:00 -04:00
|
|
|
/**
|
|
|
|
* Build EWS method
|
2010-07-10 20:13:28 -04:00
|
|
|
*
|
|
|
|
* @param itemType item type
|
|
|
|
* @param methodName method name
|
2010-05-18 07:50:00 -04:00
|
|
|
*/
|
2010-05-20 05:22:03 -04:00
|
|
|
public EWSMethod(String itemType, String methodName) {
|
2010-08-03 18:22:13 -04:00
|
|
|
this(itemType, methodName, itemType + 's');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build EWS method
|
|
|
|
*
|
2010-08-17 09:39:14 -04:00
|
|
|
* @param itemType item type
|
|
|
|
* @param methodName method name
|
2010-08-03 18:22:13 -04:00
|
|
|
* @param responseCollectionName item response collection name
|
|
|
|
*/
|
|
|
|
public EWSMethod(String itemType, String methodName, String responseCollectionName) {
|
2010-05-18 07:50:00 -04:00
|
|
|
super("/ews/exchange.asmx");
|
2010-05-20 05:22:03 -04:00
|
|
|
this.itemType = itemType;
|
|
|
|
this.methodName = methodName;
|
2010-08-03 18:22:13 -04:00
|
|
|
this.responseCollectionName = responseCollectionName;
|
2010-05-18 07:50:00 -04:00
|
|
|
setRequestEntity(new RequestEntity() {
|
|
|
|
byte[] content;
|
|
|
|
|
|
|
|
public boolean isRepeatable() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void writeRequest(OutputStream outputStream) throws IOException {
|
|
|
|
if (content == null) {
|
|
|
|
content = generateSoapEnvelope();
|
|
|
|
}
|
|
|
|
outputStream.write(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getContentLength() {
|
|
|
|
if (content == null) {
|
|
|
|
content = generateSoapEnvelope();
|
|
|
|
}
|
|
|
|
return content.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getContentType() {
|
2010-07-27 08:58:23 -04:00
|
|
|
return "text/xml; charset=UTF-8";
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return "POST";
|
|
|
|
}
|
|
|
|
|
2010-05-20 05:22:03 -04:00
|
|
|
protected void addAdditionalProperty(FieldURI additionalProperty) {
|
|
|
|
if (additionalProperties == null) {
|
|
|
|
additionalProperties = new HashSet<FieldURI>();
|
|
|
|
}
|
|
|
|
additionalProperties.add(additionalProperty);
|
|
|
|
}
|
|
|
|
|
2010-07-05 09:48:43 -04:00
|
|
|
protected void addMethodOption(AttributeOption attributeOption) {
|
|
|
|
if (methodOptions == null) {
|
|
|
|
methodOptions = new HashSet<AttributeOption>();
|
|
|
|
}
|
|
|
|
methodOptions.add(attributeOption);
|
|
|
|
}
|
|
|
|
|
2010-05-26 17:40:08 -04:00
|
|
|
protected void setSearchExpression(SearchExpression searchExpression) {
|
|
|
|
this.searchExpression = searchExpression;
|
|
|
|
}
|
|
|
|
|
2010-05-18 13:05:12 -04:00
|
|
|
protected void writeShape(Writer writer) throws IOException {
|
2010-05-18 07:50:00 -04:00
|
|
|
if (baseShape != null) {
|
|
|
|
writer.write("<m:");
|
2010-05-20 05:22:03 -04:00
|
|
|
writer.write(itemType);
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write("Shape>");
|
|
|
|
baseShape.write(writer);
|
2010-09-01 10:56:08 -04:00
|
|
|
if (includeMimeContent) {
|
|
|
|
writer.write("<t:IncludeMimeContent>true</t:IncludeMimeContent>");
|
|
|
|
}
|
2010-05-20 05:22:03 -04:00
|
|
|
if (additionalProperties != null) {
|
|
|
|
writer.write("<t:AdditionalProperties>");
|
2010-06-07 17:17:07 -04:00
|
|
|
StringBuilder buffer = new StringBuilder();
|
2010-05-20 05:22:03 -04:00
|
|
|
for (FieldURI fieldURI : additionalProperties) {
|
2010-06-07 17:17:07 -04:00
|
|
|
fieldURI.appendTo(buffer);
|
2010-05-20 05:22:03 -04:00
|
|
|
}
|
2010-06-07 17:17:07 -04:00
|
|
|
writer.write(buffer.toString());
|
2010-05-20 05:22:03 -04:00
|
|
|
writer.write("</t:AdditionalProperties>");
|
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write("</m:");
|
2010-05-20 05:22:03 -04:00
|
|
|
writer.write(itemType);
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write("Shape>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-20 05:22:03 -04:00
|
|
|
protected void writeItemId(Writer writer) throws IOException {
|
|
|
|
if (itemId != null) {
|
2010-07-05 05:58:18 -04:00
|
|
|
if (updates == null) {
|
|
|
|
writer.write("<m:ItemIds>");
|
|
|
|
}
|
2010-05-20 05:22:03 -04:00
|
|
|
itemId.write(writer);
|
2010-07-05 05:58:18 -04:00
|
|
|
if (updates == null) {
|
|
|
|
writer.write("</m:ItemIds>");
|
|
|
|
}
|
2010-05-20 05:22:03 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-17 06:45:21 -04:00
|
|
|
protected void writeParentItemId(Writer writer) throws IOException {
|
|
|
|
if (parentItemId != null) {
|
|
|
|
writer.write("<m:ParentItemId Id=\"");
|
|
|
|
writer.write(parentItemId.id);
|
|
|
|
if (parentItemId.changeKey != null) {
|
|
|
|
writer.write("\" ChangeKey=\"");
|
|
|
|
writer.write(parentItemId.changeKey);
|
|
|
|
}
|
|
|
|
writer.write("\"/>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-18 13:05:12 -04:00
|
|
|
protected void writeFolderId(Writer writer) throws IOException {
|
|
|
|
if (folderId != null) {
|
2010-06-29 10:15:50 -04:00
|
|
|
if (updates == null) {
|
|
|
|
writer.write("<m:FolderIds>");
|
|
|
|
}
|
2010-05-18 13:05:12 -04:00
|
|
|
folderId.write(writer);
|
2010-06-29 10:15:50 -04:00
|
|
|
if (updates == null) {
|
|
|
|
writer.write("</m:FolderIds>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-05 05:58:18 -04:00
|
|
|
protected void writeSavedItemFolderId(Writer writer) throws IOException {
|
|
|
|
if (savedItemFolderId != null) {
|
|
|
|
writer.write("<m:SavedItemFolderId>");
|
|
|
|
savedItemFolderId.write(writer);
|
|
|
|
writer.write("</m:SavedItemFolderId>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-29 10:15:50 -04:00
|
|
|
protected void writeToFolderId(Writer writer) throws IOException {
|
|
|
|
if (toFolderId != null) {
|
|
|
|
writer.write("<m:ToFolderId>");
|
|
|
|
toFolderId.write(writer);
|
|
|
|
writer.write("</m:ToFolderId>");
|
2010-05-18 13:05:12 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void writeParentFolderId(Writer writer) throws IOException {
|
|
|
|
if (parentFolderId != null) {
|
2010-05-26 17:40:08 -04:00
|
|
|
writer.write("<m:ParentFolderId");
|
|
|
|
if (item == null) {
|
|
|
|
writer.write("s");
|
|
|
|
}
|
|
|
|
writer.write(">");
|
2010-05-18 13:05:12 -04:00
|
|
|
parentFolderId.write(writer);
|
2010-05-26 17:40:08 -04:00
|
|
|
writer.write("</m:ParentFolderId");
|
|
|
|
if (item == null) {
|
|
|
|
writer.write("s");
|
|
|
|
}
|
|
|
|
writer.write(">");
|
2010-05-21 04:44:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void writeItem(Writer writer) throws IOException {
|
|
|
|
if (item != null) {
|
|
|
|
writer.write("<m:");
|
|
|
|
writer.write(itemType);
|
|
|
|
writer.write("s>");
|
|
|
|
item.write(writer);
|
|
|
|
writer.write("</m:");
|
|
|
|
writer.write(itemType);
|
|
|
|
writer.write("s>");
|
2010-05-18 13:05:12 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-26 17:40:08 -04:00
|
|
|
protected void writeRestriction(Writer writer) throws IOException {
|
|
|
|
if (searchExpression != null) {
|
|
|
|
writer.write("<m:Restriction>");
|
2010-06-07 17:17:07 -04:00
|
|
|
StringBuilder buffer = new StringBuilder();
|
|
|
|
searchExpression.appendTo(buffer);
|
|
|
|
writer.write(buffer.toString());
|
2010-05-26 17:40:08 -04:00
|
|
|
writer.write("</m:Restriction>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-29 10:15:50 -04:00
|
|
|
protected void startChanges(Writer writer) throws IOException {
|
2010-07-10 20:13:28 -04:00
|
|
|
//noinspection VariableNotUsedInsideIf
|
2010-06-29 10:15:50 -04:00
|
|
|
if (updates != null) {
|
|
|
|
writer.write("<m:");
|
|
|
|
writer.write(itemType);
|
|
|
|
writer.write("Changes>");
|
|
|
|
writer.write("<t:");
|
|
|
|
writer.write(itemType);
|
|
|
|
writer.write("Change>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void writeUpdates(Writer writer) throws IOException {
|
|
|
|
if (updates != null) {
|
|
|
|
writer.write("<t:Updates>");
|
|
|
|
for (FieldUpdate fieldUpdate : updates) {
|
2010-09-17 06:44:56 -04:00
|
|
|
fieldUpdate.write(itemType, writer);
|
2010-06-29 10:15:50 -04:00
|
|
|
}
|
|
|
|
writer.write("</t:Updates>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-27 15:26:54 -04:00
|
|
|
protected void writeUnresolvedEntry(Writer writer) throws IOException {
|
|
|
|
if (unresolvedEntry != null) {
|
|
|
|
unresolvedEntry.write(writer);
|
|
|
|
}
|
|
|
|
}
|
2010-06-29 10:15:50 -04:00
|
|
|
|
|
|
|
protected void endChanges(Writer writer) throws IOException {
|
2010-07-10 20:13:28 -04:00
|
|
|
//noinspection VariableNotUsedInsideIf
|
2010-06-29 10:15:50 -04:00
|
|
|
if (updates != null) {
|
|
|
|
writer.write("</t:");
|
|
|
|
writer.write(itemType);
|
|
|
|
writer.write("Change>");
|
|
|
|
writer.write("</m:");
|
|
|
|
writer.write(itemType);
|
|
|
|
writer.write("Changes>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-18 07:50:00 -04:00
|
|
|
protected byte[] generateSoapEnvelope() {
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
try {
|
|
|
|
OutputStreamWriter writer = new OutputStreamWriter(baos, "UTF-8");
|
|
|
|
writer.write("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
|
|
|
|
"xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\" " +
|
|
|
|
"xmlns:m=\"http://schemas.microsoft.com/exchange/services/2006/messages\">" +
|
2010-07-27 08:58:23 -04:00
|
|
|
"");
|
|
|
|
if (serverVersion != null) {
|
|
|
|
writer.write("<soap:Header><t:RequestServerVersion Version=\"");
|
|
|
|
writer.write(serverVersion);
|
|
|
|
writer.write("\"/></soap:Header>");
|
|
|
|
}
|
|
|
|
|
|
|
|
writer.write("<soap:Body>");
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write("<m:");
|
2010-05-20 05:22:03 -04:00
|
|
|
writer.write(methodName);
|
2010-05-18 07:50:00 -04:00
|
|
|
if (traversal != null) {
|
|
|
|
traversal.write(writer);
|
|
|
|
}
|
2010-05-21 04:44:43 -04:00
|
|
|
if (deleteType != null) {
|
|
|
|
deleteType.write(writer);
|
|
|
|
}
|
2010-07-05 09:48:43 -04:00
|
|
|
if (methodOptions != null) {
|
|
|
|
for (AttributeOption attributeOption : methodOptions) {
|
|
|
|
attributeOption.write(writer);
|
|
|
|
}
|
2010-07-05 05:58:18 -04:00
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write(">");
|
2010-05-18 13:05:12 -04:00
|
|
|
writeSoapBody(writer);
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write("</m:");
|
2010-05-20 05:22:03 -04:00
|
|
|
writer.write(methodName);
|
2010-05-18 07:50:00 -04:00
|
|
|
writer.write(">");
|
|
|
|
writer.write("</soap:Body>" +
|
|
|
|
"</soap:Envelope>");
|
|
|
|
writer.flush();
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
return baos.toByteArray();
|
|
|
|
}
|
|
|
|
|
2010-05-18 13:05:12 -04:00
|
|
|
protected void writeSoapBody(Writer writer) throws IOException {
|
2010-06-29 10:15:50 -04:00
|
|
|
startChanges(writer);
|
2010-05-18 13:05:12 -04:00
|
|
|
writeShape(writer);
|
2010-07-27 16:34:43 -04:00
|
|
|
writeIndexedPageItemView(writer);
|
2010-05-26 17:40:08 -04:00
|
|
|
writeRestriction(writer);
|
2010-05-18 13:05:12 -04:00
|
|
|
writeParentFolderId(writer);
|
2010-06-29 10:15:50 -04:00
|
|
|
writeToFolderId(writer);
|
2010-07-05 11:03:35 -04:00
|
|
|
writeItemId(writer);
|
2010-07-17 06:45:21 -04:00
|
|
|
writeParentItemId(writer);
|
|
|
|
writeAttachments(writer);
|
|
|
|
writeAttachmentId(writer);
|
2010-05-18 13:05:12 -04:00
|
|
|
writeFolderId(writer);
|
2010-07-05 05:58:18 -04:00
|
|
|
writeSavedItemFolderId(writer);
|
2010-05-21 04:44:43 -04:00
|
|
|
writeItem(writer);
|
2010-06-29 10:15:50 -04:00
|
|
|
writeUpdates(writer);
|
2010-07-27 15:26:54 -04:00
|
|
|
writeUnresolvedEntry(writer);
|
2010-06-29 10:15:50 -04:00
|
|
|
endChanges(writer);
|
2010-05-18 13:05:12 -04:00
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
|
2010-07-28 13:11:18 -04:00
|
|
|
|
2010-07-27 16:34:43 -04:00
|
|
|
protected void writeIndexedPageItemView(Writer writer) throws IOException {
|
|
|
|
if (maxCount > 0) {
|
2010-08-17 09:39:14 -04:00
|
|
|
writer.write("<m:IndexedPageItemView MaxEntriesReturned=\"");
|
2010-07-27 16:34:43 -04:00
|
|
|
writer.write(String.valueOf(maxCount));
|
2010-12-08 16:39:55 -05:00
|
|
|
writer.write("\" Offset=\"");
|
|
|
|
writer.write(String.valueOf(offset));
|
|
|
|
writer.write("\" BasePoint=\"Beginning\"/>");
|
|
|
|
|
2010-07-27 16:34:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void writeAttachmentId(Writer writer) throws IOException {
|
2010-07-17 06:45:21 -04:00
|
|
|
if (attachmentId != null) {
|
2010-07-18 19:36:25 -04:00
|
|
|
if ("CreateAttachment".equals(methodName)) {
|
|
|
|
writer.write("<m:AttachmentShape>");
|
|
|
|
writer.write("<t:IncludeMimeContent>true</t:IncludeMimeContent>");
|
|
|
|
writer.write("</m:AttachmentShape>");
|
|
|
|
}
|
2010-07-17 06:45:21 -04:00
|
|
|
writer.write("<m:AttachmentIds>");
|
|
|
|
writer.write("<t:AttachmentId Id=\"");
|
|
|
|
writer.write(attachmentId);
|
|
|
|
writer.write("\"/>");
|
|
|
|
writer.write("</m:AttachmentIds>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void writeAttachments(Writer writer) throws IOException {
|
|
|
|
if (attachment != null) {
|
|
|
|
writer.write("<m:Attachments>");
|
|
|
|
attachment.write(writer);
|
|
|
|
writer.write("</m:Attachments>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-27 08:58:23 -04:00
|
|
|
/**
|
2010-08-17 09:39:14 -04:00
|
|
|
* Get Exchange server version, Exchange2010 or Exchange2007_SP1
|
|
|
|
*
|
2010-07-27 08:58:23 -04:00
|
|
|
* @return server version
|
|
|
|
*/
|
|
|
|
public String getServerVersion() {
|
|
|
|
return serverVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set Exchange server version, Exchange2010 or Exchange2007_SP1
|
2010-08-17 09:39:14 -04:00
|
|
|
*
|
2010-07-27 08:58:23 -04:00
|
|
|
* @param serverVersion server version
|
|
|
|
*/
|
|
|
|
public void setServerVersion(String serverVersion) {
|
|
|
|
this.serverVersion = serverVersion;
|
|
|
|
}
|
|
|
|
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* Meeting attendee object
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public static class Attendee {
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* attendee role
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public String role;
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* attendee email address
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public String email;
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* attendee participation status
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public String partstat;
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* attendee fullname
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public String name;
|
|
|
|
}
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Item
|
|
|
|
*/
|
2010-05-21 04:44:43 -04:00
|
|
|
public static class Item extends HashMap<String, String> {
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Item type.
|
|
|
|
*/
|
2010-05-18 13:05:12 -04:00
|
|
|
public String type;
|
2010-07-05 05:58:18 -04:00
|
|
|
protected byte[] mimeContent;
|
2010-09-15 18:49:19 -04:00
|
|
|
protected List<FieldUpdate> fieldUpdates;
|
2010-07-17 06:45:21 -04:00
|
|
|
protected List<FileAttachment> attachments;
|
2010-09-21 10:02:44 -04:00
|
|
|
protected List<Attendee> attendees;
|
2010-09-24 04:30:40 -04:00
|
|
|
protected final List<String> fieldNames = new ArrayList<String>();
|
2010-05-18 07:50:00 -04:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2010-05-20 05:22:03 -04:00
|
|
|
return "type: " + type + ' ' + super.toString();
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
2010-05-21 04:44:43 -04:00
|
|
|
|
2010-08-18 06:33:25 -04:00
|
|
|
@Override
|
|
|
|
public String put(String key, String value) {
|
2010-10-05 05:41:04 -04:00
|
|
|
if (value != null) {
|
|
|
|
if (get(key) == null) {
|
|
|
|
fieldNames.add(key);
|
|
|
|
}
|
|
|
|
return super.put(key, value);
|
|
|
|
} else {
|
|
|
|
return null;
|
2010-08-18 06:33:25 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-21 04:44:43 -04:00
|
|
|
/**
|
|
|
|
* Write XML content to writer.
|
|
|
|
*
|
|
|
|
* @param writer writer
|
|
|
|
* @throws IOException on error
|
|
|
|
*/
|
|
|
|
public void write(Writer writer) throws IOException {
|
|
|
|
writer.write("<t:");
|
|
|
|
writer.write(type);
|
|
|
|
writer.write(">");
|
2010-08-18 06:33:25 -04:00
|
|
|
// write ordered fields
|
2010-09-17 06:44:56 -04:00
|
|
|
for (String key : fieldNames) {
|
2010-08-18 06:33:25 -04:00
|
|
|
if ("MeetingTimeZone".equals(key)) {
|
2010-08-17 09:39:14 -04:00
|
|
|
writer.write("<t:MeetingTimeZone TimeZoneName=\"");
|
2011-02-23 17:23:06 -05:00
|
|
|
writer.write(StringUtil.xmlEncodeAttribute(get(key)));
|
2010-08-17 09:39:14 -04:00
|
|
|
writer.write("\"></t:MeetingTimeZone>");
|
2010-08-18 06:33:25 -04:00
|
|
|
} else if ("StartTimeZone".equals(key)) {
|
|
|
|
writer.write("<t:StartTimeZone Id=\"");
|
2011-02-23 17:23:06 -05:00
|
|
|
writer.write(StringUtil.xmlEncodeAttribute(get(key)));
|
2010-08-18 06:33:25 -04:00
|
|
|
writer.write("\"></t:StartTimeZone>");
|
2010-08-17 09:39:14 -04:00
|
|
|
} else {
|
|
|
|
writer.write("<t:");
|
2010-08-18 06:33:25 -04:00
|
|
|
writer.write(key);
|
2010-08-17 09:39:14 -04:00
|
|
|
writer.write(">");
|
2010-08-18 06:33:25 -04:00
|
|
|
writer.write(StringUtil.xmlEncode(get(key)));
|
2010-08-17 09:39:14 -04:00
|
|
|
writer.write("</t:");
|
2010-08-18 06:33:25 -04:00
|
|
|
writer.write(key);
|
2010-08-17 09:39:14 -04:00
|
|
|
writer.write(">");
|
|
|
|
}
|
2010-05-21 04:44:43 -04:00
|
|
|
}
|
2010-07-05 05:58:18 -04:00
|
|
|
if (mimeContent != null) {
|
|
|
|
writer.write("<t:MimeContent>");
|
|
|
|
writer.write(new String(mimeContent));
|
|
|
|
writer.write("</t:MimeContent>");
|
|
|
|
}
|
|
|
|
if (fieldUpdates != null) {
|
|
|
|
for (FieldUpdate fieldUpdate : fieldUpdates) {
|
|
|
|
fieldUpdate.write(null, writer);
|
|
|
|
}
|
|
|
|
}
|
2010-05-21 04:44:43 -04:00
|
|
|
writer.write("</t:");
|
|
|
|
writer.write(type);
|
|
|
|
writer.write(">");
|
|
|
|
}
|
2010-06-07 17:17:07 -04:00
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Field updates.
|
|
|
|
*
|
|
|
|
* @param fieldUpdates field updates
|
|
|
|
*/
|
2010-09-15 18:49:19 -04:00
|
|
|
public void setFieldUpdates(List<FieldUpdate> fieldUpdates) {
|
2010-07-05 05:58:18 -04:00
|
|
|
this.fieldUpdates = fieldUpdates;
|
|
|
|
}
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Get property value as int
|
|
|
|
*
|
|
|
|
* @param key property response name
|
|
|
|
* @return property value
|
|
|
|
*/
|
2010-06-07 17:17:07 -04:00
|
|
|
public int getInt(String key) {
|
|
|
|
int result = 0;
|
|
|
|
String value = get(key);
|
|
|
|
if (value != null && value.length() > 0) {
|
|
|
|
result = Integer.parseInt(value);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2010-06-10 16:47:55 -04:00
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Get property value as long
|
|
|
|
*
|
|
|
|
* @param key property response name
|
|
|
|
* @return property value
|
|
|
|
*/
|
2010-07-01 12:12:57 -04:00
|
|
|
public long getLong(String key) {
|
|
|
|
long result = 0;
|
|
|
|
String value = get(key);
|
|
|
|
if (value != null && value.length() > 0) {
|
|
|
|
result = Long.parseLong(value);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Get property value as boolean
|
|
|
|
*
|
|
|
|
* @param key property response name
|
|
|
|
* @return property value
|
|
|
|
*/
|
2010-06-10 16:47:55 -04:00
|
|
|
public boolean getBoolean(String key) {
|
|
|
|
boolean result = false;
|
|
|
|
String value = get(key);
|
|
|
|
if (value != null && value.length() > 0) {
|
|
|
|
result = Boolean.parseBoolean(value);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-07-19 05:22:42 -04:00
|
|
|
/**
|
|
|
|
* Get file attachment by file name
|
2010-07-21 12:42:46 -04:00
|
|
|
*
|
2010-07-19 05:22:42 -04:00
|
|
|
* @param attachmentName attachment name
|
|
|
|
* @return attachment
|
|
|
|
*/
|
2010-07-17 06:45:21 -04:00
|
|
|
public FileAttachment getAttachmentByName(String attachmentName) {
|
|
|
|
FileAttachment result = null;
|
|
|
|
if (attachments != null) {
|
2010-07-18 19:36:25 -04:00
|
|
|
for (FileAttachment attachment : attachments) {
|
2010-07-17 06:45:21 -04:00
|
|
|
if (attachmentName.equals(attachment.name)) {
|
|
|
|
result = attachment;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2010-09-21 10:02:44 -04:00
|
|
|
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* Get all attendees.
|
2010-10-05 05:41:04 -04:00
|
|
|
*
|
2010-09-24 04:44:13 -04:00
|
|
|
* @return all attendees
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public List<Attendee> getAttendees() {
|
|
|
|
return attendees;
|
|
|
|
}
|
|
|
|
|
2010-09-24 04:44:13 -04:00
|
|
|
/**
|
|
|
|
* Add attendee.
|
2010-10-05 05:41:04 -04:00
|
|
|
*
|
2010-09-24 04:44:13 -04:00
|
|
|
* @param attendee attendee object
|
|
|
|
*/
|
2010-09-21 10:02:44 -04:00
|
|
|
public void addAttendee(Attendee attendee) {
|
|
|
|
if (attendees == null) {
|
|
|
|
attendees = new ArrayList<Attendee>();
|
|
|
|
}
|
|
|
|
attendees.add(attendee);
|
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Check method success.
|
|
|
|
*
|
|
|
|
* @throws EWSException on error
|
|
|
|
*/
|
2010-06-29 10:15:50 -04:00
|
|
|
public void checkSuccess() throws EWSException {
|
|
|
|
if (errorDetail != null) {
|
2010-07-28 13:11:18 -04:00
|
|
|
if (!"ErrorAccessDenied".equals(errorDetail)
|
2010-09-15 18:49:19 -04:00
|
|
|
&& !"ErrorMailRecipientNotFound".equals(errorDetail)
|
|
|
|
&& !"ErrorItemNotFound".equals(errorDetail)
|
|
|
|
) {
|
2010-07-21 12:42:46 -04:00
|
|
|
try {
|
|
|
|
throw new EWSException(errorDetail + "\n request: " + new String(generateSoapEnvelope(), "UTF-8"));
|
|
|
|
} catch (UnsupportedEncodingException e) {
|
|
|
|
throw new EWSException(e.getMessage());
|
|
|
|
}
|
2010-07-20 09:30:39 -04:00
|
|
|
}
|
2010-06-29 10:15:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-25 07:34:37 -04:00
|
|
|
@Override
|
2010-07-21 12:42:46 -04:00
|
|
|
public int getStatusCode() {
|
|
|
|
if ("ErrorAccessDenied".equals(errorDetail)) {
|
|
|
|
return HttpStatus.SC_FORBIDDEN;
|
|
|
|
} else {
|
|
|
|
return super.getStatusCode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Get response items.
|
|
|
|
*
|
|
|
|
* @return response items
|
|
|
|
* @throws EWSException on error
|
|
|
|
*/
|
2010-06-29 10:15:50 -04:00
|
|
|
public List<Item> getResponseItems() throws EWSException {
|
|
|
|
checkSuccess();
|
2010-09-01 17:58:11 -04:00
|
|
|
if (responseItems != null) {
|
|
|
|
return responseItems;
|
|
|
|
} else {
|
|
|
|
return new ArrayList<Item>();
|
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Get single response item.
|
|
|
|
*
|
|
|
|
* @return response item
|
|
|
|
* @throws EWSException on error
|
|
|
|
*/
|
2010-06-29 10:15:50 -04:00
|
|
|
public Item getResponseItem() throws EWSException {
|
|
|
|
checkSuccess();
|
2010-05-20 09:07:00 -04:00
|
|
|
if (responseItems != null && responseItems.size() == 1) {
|
|
|
|
return responseItems.get(0);
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-10 20:13:28 -04:00
|
|
|
/**
|
|
|
|
* Get response mime content.
|
|
|
|
*
|
|
|
|
* @return mime content
|
|
|
|
* @throws EWSException on error
|
|
|
|
*/
|
2010-06-29 10:15:50 -04:00
|
|
|
public byte[] getMimeContent() throws EWSException {
|
|
|
|
checkSuccess();
|
2010-07-05 05:58:18 -04:00
|
|
|
Item responseItem = getResponseItem();
|
|
|
|
if (responseItem != null) {
|
|
|
|
return responseItem.mimeContent;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2010-05-20 09:07:00 -04:00
|
|
|
}
|
|
|
|
|
2010-05-18 07:50:00 -04:00
|
|
|
protected String handleTag(XMLStreamReader reader, String localName) throws XMLStreamException {
|
|
|
|
String result = null;
|
|
|
|
int event = reader.getEventType();
|
|
|
|
if (event == XMLStreamConstants.START_ELEMENT && localName.equals(reader.getLocalName())) {
|
|
|
|
while (reader.hasNext() &&
|
|
|
|
!((event == XMLStreamConstants.END_ELEMENT && localName.equals(reader.getLocalName())))) {
|
|
|
|
event = reader.next();
|
|
|
|
if (event == XMLStreamConstants.CHARACTERS) {
|
|
|
|
result = reader.getText();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void handleErrors(XMLStreamReader reader) throws XMLStreamException {
|
|
|
|
String result = handleTag(reader, "ResponseCode");
|
2010-08-09 16:15:28 -04:00
|
|
|
if (errorDetail == null && result != null
|
|
|
|
&& !"NoError".equals(result)
|
|
|
|
&& !"ErrorNameResolutionMultipleResults".equals(result)
|
|
|
|
&& !"ErrorNameResolutionNoResults".equals(result)
|
2010-08-18 06:33:25 -04:00
|
|
|
&& !"ErrorFolderExists".equals(result)
|
2010-08-09 16:15:28 -04:00
|
|
|
) {
|
2010-05-18 07:50:00 -04:00
|
|
|
errorDetail = result;
|
|
|
|
}
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader, "faultstring")) {
|
2010-10-05 05:41:04 -04:00
|
|
|
errorDetail = XMLStreamUtil.getElementText(reader);
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Item handleItem(XMLStreamReader reader) throws XMLStreamException {
|
2010-07-05 05:58:18 -04:00
|
|
|
Item responseItem = new Item();
|
|
|
|
responseItem.type = reader.getLocalName();
|
2010-08-28 16:21:31 -04:00
|
|
|
while (reader.hasNext() && !XMLStreamUtil.isEndTag(reader, responseItem.type)) {
|
2010-09-01 10:56:08 -04:00
|
|
|
reader.next();
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
2010-05-18 15:21:19 -04:00
|
|
|
String tagLocalName = reader.getLocalName();
|
|
|
|
String value = null;
|
2010-05-20 05:22:03 -04:00
|
|
|
if ("ExtendedProperty".equals(tagLocalName)) {
|
2010-07-05 05:58:18 -04:00
|
|
|
addExtendedPropertyValue(reader, responseItem);
|
2010-05-20 09:07:00 -04:00
|
|
|
} else if (tagLocalName.endsWith("MimeContent")) {
|
2010-07-05 05:58:18 -04:00
|
|
|
handleMimeContent(reader, responseItem);
|
2010-07-19 05:22:42 -04:00
|
|
|
} else if ("Attachments".equals(tagLocalName)) {
|
|
|
|
responseItem.attachments = handleAttachments(reader);
|
2010-09-21 09:12:19 -04:00
|
|
|
} else if ("EmailAddresses".equals(tagLocalName)) {
|
|
|
|
handleEmailAddresses(reader, responseItem);
|
2010-09-21 10:02:44 -04:00
|
|
|
} else if ("RequiredAttendees".equals(tagLocalName) || "OptionalAttendees".equals(tagLocalName)) {
|
|
|
|
handleAttendees(reader, responseItem, tagLocalName);
|
2010-05-20 05:22:03 -04:00
|
|
|
} else {
|
|
|
|
if (tagLocalName.endsWith("Id")) {
|
|
|
|
value = getAttributeValue(reader, "Id");
|
2010-06-29 10:15:50 -04:00
|
|
|
// get change key
|
2010-07-05 05:58:18 -04:00
|
|
|
responseItem.put("ChangeKey", getAttributeValue(reader, "ChangeKey"));
|
2010-05-20 05:22:03 -04:00
|
|
|
}
|
|
|
|
if (value == null) {
|
|
|
|
value = getTagContent(reader);
|
|
|
|
}
|
|
|
|
if (value != null) {
|
2010-07-05 05:58:18 -04:00
|
|
|
responseItem.put(tagLocalName, value);
|
2010-05-20 05:22:03 -04:00
|
|
|
}
|
2010-05-18 13:05:12 -04:00
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
}
|
2010-07-05 05:58:18 -04:00
|
|
|
return responseItem;
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
|
2010-09-21 09:12:19 -04:00
|
|
|
protected void handleEmailAddresses(XMLStreamReader reader, Item item) throws XMLStreamException {
|
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "EmailAddresses"))) {
|
|
|
|
reader.next();
|
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
|
|
|
String tagLocalName = reader.getLocalName();
|
|
|
|
if ("Entry".equals(tagLocalName)) {
|
2010-10-05 05:41:04 -04:00
|
|
|
item.put(reader.getAttributeValue(null, "Key"), XMLStreamUtil.getElementText(reader));
|
2010-09-21 09:12:19 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-21 10:02:44 -04:00
|
|
|
protected void handleAttendees(XMLStreamReader reader, Item item, String attendeeType) throws XMLStreamException {
|
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, attendeeType))) {
|
|
|
|
reader.next();
|
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
|
|
|
String tagLocalName = reader.getLocalName();
|
|
|
|
if ("Attendee".equals(tagLocalName)) {
|
|
|
|
handleAttendee(reader, item, attendeeType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void handleAttendee(XMLStreamReader reader, Item item, String attendeeType) throws XMLStreamException {
|
|
|
|
Attendee attendee = new Attendee();
|
|
|
|
if ("RequiredAttendees".equals(attendeeType)) {
|
|
|
|
attendee.role = "REQ-PARTICIPANT";
|
|
|
|
} else {
|
|
|
|
attendee.role = "OPT-PARTICIPANT";
|
|
|
|
}
|
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Attendee"))) {
|
|
|
|
reader.next();
|
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
|
|
|
String tagLocalName = reader.getLocalName();
|
|
|
|
if ("EmailAddress".equals(tagLocalName)) {
|
|
|
|
attendee.email = reader.getElementText();
|
|
|
|
} else if ("Name".equals(tagLocalName)) {
|
2010-10-05 05:41:04 -04:00
|
|
|
attendee.name = XMLStreamUtil.getElementText(reader);
|
2010-09-21 10:02:44 -04:00
|
|
|
} else if ("ResponseType".equals(tagLocalName)) {
|
2010-10-05 05:41:04 -04:00
|
|
|
String responseType = XMLStreamUtil.getElementText(reader);
|
2010-09-21 10:02:44 -04:00
|
|
|
if ("Accept".equals(responseType)) {
|
|
|
|
attendee.partstat = "ACCEPTED";
|
|
|
|
} else if ("Tentative".equals(responseType)) {
|
|
|
|
attendee.partstat = "TENTATIVE";
|
|
|
|
} else if ("Decline".equals(responseType)) {
|
|
|
|
attendee.partstat = "DECLINED";
|
|
|
|
} else {
|
|
|
|
attendee.partstat = "NEEDS-ACTION";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
item.addAttendee(attendee);
|
|
|
|
}
|
|
|
|
|
2010-07-19 05:22:42 -04:00
|
|
|
protected List<FileAttachment> handleAttachments(XMLStreamReader reader) throws XMLStreamException {
|
2010-07-17 06:45:21 -04:00
|
|
|
List<FileAttachment> attachments = new ArrayList<FileAttachment>();
|
2010-08-28 16:21:31 -04:00
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Attachments"))) {
|
2010-09-01 10:56:08 -04:00
|
|
|
reader.next();
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
2010-07-17 06:45:21 -04:00
|
|
|
String tagLocalName = reader.getLocalName();
|
2010-07-19 05:22:42 -04:00
|
|
|
if ("FileAttachment".equals(tagLocalName)) {
|
|
|
|
attachments.add(handleFileAttachment(reader));
|
2010-07-17 06:45:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return attachments;
|
|
|
|
}
|
|
|
|
|
2010-07-19 05:22:42 -04:00
|
|
|
protected FileAttachment handleFileAttachment(XMLStreamReader reader) throws XMLStreamException {
|
2010-07-17 06:45:21 -04:00
|
|
|
FileAttachment fileAttachment = new FileAttachment();
|
2010-08-28 16:21:31 -04:00
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "FileAttachment"))) {
|
2010-09-01 10:56:08 -04:00
|
|
|
reader.next();
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
2010-07-17 06:45:21 -04:00
|
|
|
String tagLocalName = reader.getLocalName();
|
2010-07-19 05:22:42 -04:00
|
|
|
if ("AttachmentId".equals(tagLocalName)) {
|
2010-07-17 06:45:21 -04:00
|
|
|
fileAttachment.attachmentId = getAttributeValue(reader, "Id");
|
2010-07-19 05:22:42 -04:00
|
|
|
} else if ("Name".equals(tagLocalName)) {
|
2010-07-18 19:36:25 -04:00
|
|
|
fileAttachment.name = getTagContent(reader);
|
2010-07-19 05:22:42 -04:00
|
|
|
} else if ("ContentType".equals(tagLocalName)) {
|
2010-07-18 19:36:25 -04:00
|
|
|
fileAttachment.contentType = getTagContent(reader);
|
2010-07-17 06:45:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fileAttachment;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-05 05:58:18 -04:00
|
|
|
protected void handleMimeContent(XMLStreamReader reader, Item responseItem) throws XMLStreamException {
|
2010-12-08 16:39:55 -05:00
|
|
|
if (reader instanceof TypedXMLStreamReader) {
|
2010-11-17 16:28:29 -05:00
|
|
|
// Stax2 parser: use enhanced base64 conversion
|
2010-12-08 16:39:55 -05:00
|
|
|
responseItem.mimeContent = ((TypedXMLStreamReader) reader).getElementAsBinary();
|
2010-11-17 16:28:29 -05:00
|
|
|
} else {
|
|
|
|
// failover: slow and memory consuming conversion
|
|
|
|
byte[] base64MimeContent = reader.getElementText().getBytes();
|
|
|
|
responseItem.mimeContent = Base64.decodeBase64(base64MimeContent);
|
|
|
|
}
|
2010-05-20 09:07:00 -04:00
|
|
|
}
|
|
|
|
|
2010-05-20 05:22:03 -04:00
|
|
|
protected void addExtendedPropertyValue(XMLStreamReader reader, Item item) throws XMLStreamException {
|
|
|
|
String propertyTag = null;
|
|
|
|
String propertyValue = null;
|
2010-08-28 16:21:31 -04:00
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "ExtendedProperty"))) {
|
2010-09-01 10:56:08 -04:00
|
|
|
reader.next();
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
2010-05-20 05:22:03 -04:00
|
|
|
String tagLocalName = reader.getLocalName();
|
2010-07-10 20:13:28 -04:00
|
|
|
if ("ExtendedFieldURI".equals(tagLocalName)) {
|
2010-05-20 05:22:03 -04:00
|
|
|
propertyTag = getAttributeValue(reader, "PropertyTag");
|
2010-07-13 07:27:12 -04:00
|
|
|
// property name is in PropertyId or PropertyName with DistinguishedPropertySetId
|
2010-07-07 08:29:41 -04:00
|
|
|
if (propertyTag == null) {
|
|
|
|
propertyTag = getAttributeValue(reader, "PropertyId");
|
|
|
|
}
|
2010-07-13 07:27:12 -04:00
|
|
|
if (propertyTag == null) {
|
|
|
|
propertyTag = getAttributeValue(reader, "PropertyName");
|
|
|
|
}
|
2010-07-10 20:13:28 -04:00
|
|
|
} else if ("Value".equals(tagLocalName)) {
|
2010-10-05 05:41:04 -04:00
|
|
|
propertyValue = XMLStreamUtil.getElementText(reader);
|
2010-07-13 07:27:12 -04:00
|
|
|
} else if ("Values".equals(tagLocalName)) {
|
|
|
|
StringBuilder buffer = new StringBuilder();
|
2010-08-28 16:21:31 -04:00
|
|
|
while (reader.hasNext() && !(XMLStreamUtil.isEndTag(reader, "Values"))) {
|
2010-09-01 10:56:08 -04:00
|
|
|
reader.next();
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
2010-07-13 07:27:12 -04:00
|
|
|
|
|
|
|
if (buffer.length() > 0) {
|
|
|
|
buffer.append(',');
|
|
|
|
}
|
2010-10-05 05:41:04 -04:00
|
|
|
String singleValue = XMLStreamUtil.getElementText(reader);
|
|
|
|
if (singleValue != null) {
|
|
|
|
buffer.append(singleValue);
|
|
|
|
}
|
2010-07-13 07:27:12 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
propertyValue = buffer.toString();
|
2010-05-20 05:22:03 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((propertyTag != null) && (propertyValue != null)) {
|
|
|
|
item.put(propertyTag, propertyValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-03 18:22:13 -04:00
|
|
|
protected String getTagContent(XMLStreamReader reader) throws XMLStreamException {
|
2010-05-18 15:21:19 -04:00
|
|
|
String tagLocalName = reader.getLocalName();
|
|
|
|
while (reader.hasNext() && !(reader.getEventType() == XMLStreamConstants.END_ELEMENT)) {
|
|
|
|
reader.next();
|
|
|
|
if (reader.getEventType() == XMLStreamConstants.CHARACTERS) {
|
|
|
|
return reader.getText();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// empty tag
|
|
|
|
if (reader.hasNext()) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
throw new XMLStreamException("End element for " + tagLocalName + " not found");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-19 05:22:42 -04:00
|
|
|
protected String getAttributeValue(XMLStreamReader reader, String attributeName) {
|
2010-05-18 15:21:19 -04:00
|
|
|
for (int i = 0; i < reader.getAttributeCount(); i++) {
|
2010-05-20 05:22:03 -04:00
|
|
|
if (attributeName.equals(reader.getAttributeLocalName(i))) {
|
2010-05-18 15:21:19 -04:00
|
|
|
return reader.getAttributeValue(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2010-05-18 07:50:00 -04:00
|
|
|
@Override
|
|
|
|
protected void processResponseBody(HttpState httpState, HttpConnection httpConnection) {
|
|
|
|
Header contentTypeHeader = getResponseHeader("Content-Type");
|
|
|
|
if (contentTypeHeader != null && "text/xml; charset=utf-8".equals(contentTypeHeader.getValue())) {
|
|
|
|
try {
|
2010-10-27 17:52:33 -04:00
|
|
|
processResponseStream(getResponseBodyAsStream());
|
2010-05-18 07:50:00 -04:00
|
|
|
} catch (IOException e) {
|
2010-12-17 08:06:11 -05:00
|
|
|
LOGGER.error("Error while parsing soap response: " + e, e);
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
2010-10-27 17:52:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void processResponseStream(InputStream inputStream) {
|
|
|
|
responseItems = new ArrayList<Item>();
|
|
|
|
XMLStreamReader reader;
|
|
|
|
try {
|
|
|
|
reader = XMLStreamUtil.createXMLStreamReader(inputStream);
|
|
|
|
while (reader.hasNext()) {
|
|
|
|
reader.next();
|
|
|
|
handleErrors(reader);
|
|
|
|
if (serverVersion == null && XMLStreamUtil.isStartTag(reader, "ServerVersionInfo")) {
|
|
|
|
String majorVersion = getAttributeValue(reader, "MajorVersion");
|
|
|
|
if ("14".equals(majorVersion)) {
|
|
|
|
serverVersion = "Exchange2010";
|
|
|
|
} else {
|
|
|
|
serverVersion = "Exchange2007_SP1";
|
|
|
|
}
|
2010-12-08 16:39:55 -05:00
|
|
|
} else if (XMLStreamUtil.isStartTag(reader, "RootFolder")) {
|
|
|
|
includesLastItemInRange = "true".equals(reader.getAttributeValue(null, "IncludesLastItemInRange"));
|
2010-10-27 17:52:33 -04:00
|
|
|
} else if (XMLStreamUtil.isStartTag(reader, responseCollectionName)) {
|
|
|
|
handleItems(reader);
|
|
|
|
} else {
|
|
|
|
handleCustom(reader);
|
|
|
|
}
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
2010-10-27 17:52:33 -04:00
|
|
|
|
|
|
|
} catch (XMLStreamException e) {
|
2010-12-17 08:06:11 -05:00
|
|
|
LOGGER.error("Error while parsing soap response: " + e, e);
|
2010-10-27 17:52:33 -04:00
|
|
|
}
|
|
|
|
if (errorDetail != null) {
|
2010-12-17 08:06:11 -05:00
|
|
|
LOGGER.debug(errorDetail);
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-28 13:11:18 -04:00
|
|
|
@SuppressWarnings({"NoopMethodInAbstractClass"})
|
|
|
|
protected void handleCustom(XMLStreamReader reader) throws XMLStreamException {
|
|
|
|
// override to handle custom content
|
|
|
|
}
|
|
|
|
|
2010-05-18 13:05:12 -04:00
|
|
|
private void handleItems(XMLStreamReader reader) throws XMLStreamException {
|
2010-08-28 16:21:31 -04:00
|
|
|
while (reader.hasNext() && !XMLStreamUtil.isEndTag(reader, responseCollectionName)) {
|
2010-09-01 10:56:08 -04:00
|
|
|
reader.next();
|
2010-08-28 16:21:31 -04:00
|
|
|
if (XMLStreamUtil.isStartTag(reader)) {
|
2010-05-18 13:05:12 -04:00
|
|
|
responseItems.add(handleItem(reader));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-05-18 07:50:00 -04:00
|
|
|
}
|