microsoft.exchange.webservices.data.core.ExchangeServiceBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ews-java-api Show documentation
Show all versions of ews-java-api Show documentation
Exchange Web Services (EWS) Java API
/*
* The MIT License
* Copyright (c) 2012 Microsoft Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package microsoft.exchange.webservices.data.core;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TimeZone;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import microsoft.exchange.webservices.data.EWSConstants;
import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
import microsoft.exchange.webservices.data.core.enumeration.misc.TraceFlags;
import microsoft.exchange.webservices.data.core.exception.http.EWSHttpException;
import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
import microsoft.exchange.webservices.data.core.exception.service.remote.AccountIsLockedException;
import microsoft.exchange.webservices.data.core.request.HttpClientWebRequest;
import microsoft.exchange.webservices.data.core.request.HttpWebRequest;
import microsoft.exchange.webservices.data.credential.ExchangeCredentials;
import microsoft.exchange.webservices.data.misc.EwsTraceListener;
import microsoft.exchange.webservices.data.misc.ITraceListener;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.CookieStore;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
/**
* Represents an abstract binding to an Exchange Service.
*/
public abstract class ExchangeServiceBase implements Closeable {
private static final Log LOG = LogFactory.getLog(ExchangeService.class);
/**
* The credential.
*/
private ExchangeCredentials credentials;
/**
* The use default credential.
*/
private boolean useDefaultCredentials;
/**
* The binary secret.
*/
private static byte[] binarySecret;
/**
* The timeout.
*/
private int timeout = 100000;
/**
* The trace enabled.
*/
private boolean traceEnabled;
/**
* The trace flags.
*/
private EnumSet traceFlags = EnumSet.allOf(TraceFlags.class);
/**
* The trace listener.
*/
private ITraceListener traceListener = new EwsTraceListener();
/**
* The pre authenticate.
*/
private boolean preAuthenticate;
/**
* The user agent.
*/
private String userAgent = ExchangeServiceBase.defaultUserAgent;
/**
* The accept gzip encoding.
*/
private boolean acceptGzipEncoding = true;
/**
* The requested server version.
*/
private ExchangeVersion requestedServerVersion = ExchangeVersion.Exchange2010_SP2;
/**
* The server info.
*/
private ExchangeServerInfo serverInfo;
private Map httpHeaders = new HashMap();
private Map httpResponseHeaders = new HashMap();
private WebProxy webProxy;
protected CloseableHttpClient httpClient;
protected boolean externalHttpClient = false;
protected HttpClientContext httpContext;
protected CloseableHttpClient httpPoolingClient;
protected boolean externalHttpPoolingClient = false;
private int maximumPoolingConnections = 10;
// protected HttpClientWebRequest request = null;
// protected static HttpStatusCode AccountIsLocked = (HttpStatusCode)456;
/**
* Default UserAgent.
*/
private static String defaultUserAgent = "ExchangeServicesClient/" + EwsUtilities.getBuildVersion();
/**
* Initializes a new instance.
*
* This constructor performs the initialization of the HTTP connection manager, so it should be called by
* every other constructor.
*/
protected ExchangeServiceBase() {
setUseDefaultCredentials(true);
initializeHttpClient();
initializeHttpContext();
}
protected ExchangeServiceBase(CloseableHttpClient httpClient, CloseableHttpClient httpPoolingClient) {
setUseDefaultCredentials(true);
if (httpClient != null) {
externalHttpClient = true;
this.httpClient = httpClient;
}
if (httpPoolingClient != null) {
externalHttpPoolingClient = true;
this.httpPoolingClient = httpPoolingClient;
}
initializeHttpContext();
}
protected ExchangeServiceBase(ExchangeVersion requestedServerVersion) {
this();
this.requestedServerVersion = requestedServerVersion;
}
protected ExchangeServiceBase(ExchangeVersion requestedServerVersion, CloseableHttpClient httpClient,
CloseableHttpClient httpPoolingClient) {
this(httpClient, httpPoolingClient);
this.requestedServerVersion = requestedServerVersion;
}
protected ExchangeServiceBase(ExchangeServiceBase service, ExchangeVersion requestedServerVersion) {
this(requestedServerVersion);
this.useDefaultCredentials = service.getUseDefaultCredentials();
this.credentials = service.getCredentials();
this.traceEnabled = service.isTraceEnabled();
this.traceListener = service.getTraceListener();
this.traceFlags = service.getTraceFlags();
this.timeout = service.getTimeout();
this.preAuthenticate = service.isPreAuthenticate();
this.userAgent = service.getUserAgent();
this.acceptGzipEncoding = service.getAcceptGzipEncoding();
this.httpHeaders = service.getHttpHeaders();
}
protected void initializeHttpClient() {
Registry registry = createConnectionSocketFactoryRegistry();
HttpClientConnectionManager httpConnectionManager = new BasicHttpClientConnectionManager(registry);
AuthenticationStrategy authStrategy = new CookieProcessingTargetAuthenticationStrategy();
httpClient = HttpClients.custom()
.setConnectionManager(httpConnectionManager)
.setTargetAuthenticationStrategy(authStrategy)
.build();
}
protected void initializeHttpPoolingClient() {
Registry registry = createConnectionSocketFactoryRegistry();
PoolingHttpClientConnectionManager httpConnectionManager = new PoolingHttpClientConnectionManager(registry);
httpConnectionManager.setMaxTotal(maximumPoolingConnections);
httpConnectionManager.setDefaultMaxPerRoute(maximumPoolingConnections);
AuthenticationStrategy authStrategy = new CookieProcessingTargetAuthenticationStrategy();
httpPoolingClient = HttpClients.custom()
.setConnectionManager(httpConnectionManager)
.setTargetAuthenticationStrategy(authStrategy)
.build();
}
/**
* Sets the maximum number of connections for the pooling connection manager which is used for
* subscriptions.
*
* Default is 10.
*
*
* @param maximumPoolingConnections Maximum number of pooling connections
*/
public void setMaximumPoolingConnections(int maximumPoolingConnections) {
if (maximumPoolingConnections < 1)
throw new IllegalArgumentException("maximumPoolingConnections must be 1 or greater");
this.maximumPoolingConnections = maximumPoolingConnections;
}
/**
* Create registry with configured {@link ConnectionSocketFactory} instances.
* Override this method to change how to work with different schemas.
*
* @return registry object
*/
protected Registry createConnectionSocketFactoryRegistry() {
try {
return RegistryBuilder.create()
.register(EWSConstants.HTTP_SCHEME, new PlainConnectionSocketFactory())
.register(EWSConstants.HTTPS_SCHEME, EwsSSLProtocolSocketFactory.build(null))
.build();
} catch (GeneralSecurityException e) {
throw new RuntimeException(
"Could not initialize ConnectionSocketFactory instances for HttpClientConnectionManager", e
);
}
}
/**
* (Re)initializes the HttpContext object. This removes any existing state (mainly cookies). Use an own
* cookie store, instead of the httpClient's global store, so cookies get reset on reinitialization
*/
private void initializeHttpContext() {
CookieStore cookieStore = new BasicCookieStore();
httpContext = HttpClientContext.create();
httpContext.setCookieStore(cookieStore);
}
@Override
public void close() {
if (!externalHttpClient) {
IOUtils.closeQuietly(httpClient);
}
if (!externalHttpPoolingClient) {
IOUtils.closeQuietly(httpPoolingClient);
}
}
// Event handlers
/**
* Calls the custom SOAP header serialisation event handlers, if defined.
*
* @param writer The XmlWriter to which to write the custom SOAP headers.
*/
public void doOnSerializeCustomSoapHeaders(XMLStreamWriter writer) {
EwsUtilities
.ewsAssert(writer != null, "ExchangeService.DoOnSerializeCustomSoapHeaders", "writer is null");
if (null != getOnSerializeCustomSoapHeaders() &&
!getOnSerializeCustomSoapHeaders().isEmpty()) {
for (ICustomXmlSerialization customSerialization : getOnSerializeCustomSoapHeaders()) {
customSerialization.CustomXmlSerialization(writer);
}
}
}
// Utilities
/**
* Creates an HttpWebRequest instance and initialises it with the
* appropriate parameters, based on the configuration of this service
* object.
*
* @param url The URL that the HttpWebRequest should target.
* @param acceptGzipEncoding If true, ask server for GZip compressed content.
* @param allowAutoRedirect If true, redirection response will be automatically followed.
* @return An initialised instance of HttpWebRequest.
* @throws ServiceLocalException the service local exception
* @throws java.net.URISyntaxException the uRI syntax exception
*/
protected HttpWebRequest prepareHttpWebRequestForUrl(URI url, boolean acceptGzipEncoding,
boolean allowAutoRedirect) throws ServiceLocalException, URISyntaxException {
// Verify that the protocol is something that we can handle
String scheme = url.getScheme();
if (!scheme.equalsIgnoreCase(EWSConstants.HTTP_SCHEME)
&& !scheme.equalsIgnoreCase(EWSConstants.HTTPS_SCHEME)) {
String strErr = String.format("Protocol %s isn't supported for service request.", scheme);
throw new ServiceLocalException(strErr);
}
HttpClientWebRequest request = new HttpClientWebRequest(httpClient, httpContext);
prepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect, request);
return request;
}
/**
* Creates an HttpWebRequest instance from a pooling connection manager and initialises it with
* the appropriate parameters, based on the configuration of this service object.
*
* This is used for subscriptions.
*
*
* @param url The URL that the HttpWebRequest should target.
* @param acceptGzipEncoding If true, ask server for GZip compressed content.
* @param allowAutoRedirect If true, redirection response will be automatically followed.
* @return An initialised instance of HttpWebRequest.
* @throws ServiceLocalException the service local exception
* @throws java.net.URISyntaxException the uRI syntax exception
*/
protected HttpWebRequest prepareHttpPoolingWebRequestForUrl(URI url, boolean acceptGzipEncoding,
boolean allowAutoRedirect) throws ServiceLocalException, URISyntaxException {
// Verify that the protocol is something that we can handle
String scheme = url.getScheme();
if (!scheme.equalsIgnoreCase(EWSConstants.HTTP_SCHEME)
&& !scheme.equalsIgnoreCase(EWSConstants.HTTPS_SCHEME)) {
String strErr = String.format("Protocol %s isn't supported for service request.", scheme);
throw new ServiceLocalException(strErr);
}
if (httpPoolingClient == null) {
initializeHttpPoolingClient();
}
HttpClientWebRequest request = new HttpClientWebRequest(httpPoolingClient, httpContext);
prepareHttpWebRequestForUrl(url, acceptGzipEncoding, allowAutoRedirect, request);
return request;
}
private void prepareHttpWebRequestForUrl(URI url, boolean acceptGzipEncoding, boolean allowAutoRedirect,
HttpClientWebRequest request) throws ServiceLocalException, URISyntaxException {
try {
request.setUrl(url.toURL());
} catch (MalformedURLException e) {
String strErr = String.format("Incorrect format : %s", url);
throw new ServiceLocalException(strErr);
}
request.setPreAuthenticate(preAuthenticate);
request.setTimeout(timeout);
request.setContentType("text/xml; charset=utf-8");
request.setAccept("text/xml");
request.setUserAgent(userAgent);
request.setAllowAutoRedirect(allowAutoRedirect);
request.setAcceptGzipEncoding(acceptGzipEncoding);
request.setHeaders(getHttpHeaders());
request.setProxy(getWebProxy());
prepareCredentials(request);
request.prepareConnection();
httpResponseHeaders.clear();
}
protected void prepareCredentials(HttpWebRequest request) throws ServiceLocalException, URISyntaxException {
request.setUseDefaultCredentials(useDefaultCredentials);
if (!useDefaultCredentials) {
if (credentials == null) {
throw new ServiceLocalException("Credentials are required to make a service request.");
}
// Make sure that credential have been authenticated if required
credentials.preAuthenticate();
// Apply credential to the request
credentials.prepareWebRequest(request);
}
}
/**
* This method doesn't handle 500 ISE errors. This is handled by the caller since
* 500 ISE typically indicates that a SOAP fault has occurred and the handling of
* a SOAP fault is currently service specific.
*
* @param httpWebResponse HTTP web response
* @param webException web exception
* @param responseHeadersTraceFlag trace flag for response headers
* @param responseTraceFlag trace flag for respone
* @throws Exception on error
*/
protected void internalProcessHttpErrorResponse(HttpWebRequest httpWebResponse, Exception webException,
TraceFlags responseHeadersTraceFlag, TraceFlags responseTraceFlag) throws Exception {
EwsUtilities.ewsAssert(500 != httpWebResponse.getResponseCode(),
"ExchangeServiceBase.InternalProcessHttpErrorResponse",
"InternalProcessHttpErrorResponse does not handle 500 ISE errors, the caller is supposed to handle this.");
this.processHttpResponseHeaders(responseHeadersTraceFlag, httpWebResponse);
// E14:321785 -- Deal with new HTTP error code indicating that account is locked.
// The "unlock" URL is returned as the status description in the response.
if (httpWebResponse.getResponseCode() == 456) {
String location = httpWebResponse.getResponseContentType();
URI accountUnlockUrl = null;
if (checkURIPath(location)) {
accountUnlockUrl = new URI(location);
}
final String message = String.format("This account is locked. Visit %s to unlock it.", accountUnlockUrl);
this.traceMessage(responseTraceFlag, message);
throw new AccountIsLockedException(message, accountUnlockUrl, webException);
}
}
/**
* @param location file path
* @return false if location is null,true if this abstract pathname is absolute
*/
public static boolean checkURIPath(String location) {
if (location == null) {
return false;
}
final File file = new File(location);
return file.isAbsolute();
}
/**
* @param httpWebResponse HTTP web response
* @param webException web exception
* @throws Exception on error
*/
protected abstract void processHttpErrorResponse(HttpWebRequest httpWebResponse, Exception webException)
throws Exception;
/**
* Determines whether tracing is enabled for specified trace flag(s).
*
* @param traceFlags The trace flags.
* @return True if tracing is enabled for specified trace flag(s).
*/
public boolean isTraceEnabledFor(TraceFlags traceFlags) {
return this.isTraceEnabled() && this.traceFlags.contains(traceFlags);
}
/**
* Logs the specified string to the TraceListener if tracing is enabled.
*
* @param traceType kind of trace entry
* @param logEntry the entry to log
* @throws XMLStreamException the XML stream exception
* @throws IOException signals that an I/O exception has occurred
*/
public void traceMessage(TraceFlags traceType, String logEntry) throws XMLStreamException, IOException {
if (this.isTraceEnabledFor(traceType)) {
String traceTypeStr = traceType.toString();
String logMessage = EwsUtilities.formatLogMessage(traceTypeStr, logEntry);
this.traceListener.trace(traceTypeStr, logMessage);
}
}
/**
* Logs the specified XML to the TraceListener if tracing is enabled.
*
* @param traceType Kind of trace entry.
* @param stream The stream containing XML.
*/
public void traceXml(TraceFlags traceType, ByteArrayOutputStream stream) {
if (this.isTraceEnabledFor(traceType)) {
String traceTypeStr = traceType.toString();
String logMessage = EwsUtilities.formatLogMessageWithXmlContent(traceTypeStr, stream);
this.traceListener.trace(traceTypeStr, logMessage);
}
}
/**
* Traces the HTTP request headers.
*
* @param traceType Kind of trace entry.
* @param request The request
* @throws EWSHttpException EWS http exception
* @throws URISyntaxException URI syntax error
* @throws IOException signals that an I/O exception has occurred
* @throws XMLStreamException the XML stream exception
*/
public void traceHttpRequestHeaders(TraceFlags traceType, HttpWebRequest request)
throws URISyntaxException, EWSHttpException, XMLStreamException, IOException {
if (this.isTraceEnabledFor(traceType)) {
String traceTypeStr = traceType.toString();
String headersAsString = EwsUtilities.formatHttpRequestHeaders(request);
String logMessage = EwsUtilities.formatLogMessage(traceTypeStr, headersAsString);
this.traceListener.trace(traceTypeStr, logMessage);
}
}
/**
* Traces the HTTP response headers.
*
* @param traceType kind of trace entry
* @param request the HttpRequest object
* @throws XMLStreamException the XML stream exception
* @throws IOException signals that an I/O exception has occurred
* @throws EWSHttpException the EWS http exception
*/
private void traceHttpResponseHeaders(TraceFlags traceType, HttpWebRequest request)
throws XMLStreamException, IOException, EWSHttpException {
if (this.isTraceEnabledFor(traceType)) {
String traceTypeStr = traceType.toString();
String headersAsString = EwsUtilities.formatHttpResponseHeaders(request);
String logMessage = EwsUtilities.formatLogMessage(traceTypeStr, headersAsString);
this.traceListener.trace(traceTypeStr, logMessage);
}
}
/**
* Converts the date time to universal date time string.
*
* @param dt the date
* @return String representation of DateTime in yyyy-MM-ddTHH:mm:ssZ format.
*/
public String convertDateTimeToUniversalDateTimeString(Date dt) {
String utcPattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
DateFormat utcFormatter = new SimpleDateFormat(utcPattern);
utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
return utcFormatter.format(dt);
}
/**
* Sets the user agent to a custom value
*
* @param userAgent User agent string to set on the service
*/
protected void setCustomUserAgent(String userAgent) {
this.userAgent = userAgent;
}
/**
* Validates this instance.
*
* @throws ServiceLocalException the service local exception
*/
public void validate() throws ServiceLocalException {
}
/**
* Gets a value indicating whether tracing is enabled.
*
* @return True is tracing is enabled
*/
public boolean isTraceEnabled() {
return this.traceEnabled;
}
/**
* Sets a value indicating whether tracing is enabled.
*
* @param traceEnabled true to enable tracing
*/
public void setTraceEnabled(boolean traceEnabled) {
this.traceEnabled = traceEnabled;
if (this.traceEnabled && (this.traceListener == null)) {
this.traceListener = new EwsTraceListener();
}
}
/**
* Gets the trace flags.
*
* @return Set of trace flags.
*/
public EnumSet getTraceFlags() {
return traceFlags;
}
/**
* Sets the trace flags.
*
* @param traceFlags A set of trace flags
*/
public void setTraceFlags(EnumSet traceFlags) {
this.traceFlags = traceFlags;
}
/**
* Gets the trace listener.
*
* @return The trace listener.
*/
public ITraceListener getTraceListener() {
return traceListener;
}
/**
* Sets the trace listener.
*
* @param traceListener the trace listener.
*/
public void setTraceListener(ITraceListener traceListener) {
this.traceListener = traceListener;
this.traceEnabled = (traceListener != null);
}
/**
* Gets the credential used to authenticate with the Exchange Web Services.
*
* @return credential
*/
public ExchangeCredentials getCredentials() {
return this.credentials;
}
/**
* Sets the credential used to authenticate with the Exchange Web Services.
* Setting the Credentials property automatically sets the
* UseDefaultCredentials to false.
*
* @param credentials Exchange credential.
*/
public void setCredentials(ExchangeCredentials credentials) {
this.credentials = credentials;
this.useDefaultCredentials = false;
// Reset the httpContext, to remove any existing authentication cookies from subsequent request
initializeHttpContext();
}
/**
* Gets a value indicating whether the credential of the user currently
* logged into Windows should be used to authenticate with the Exchange Web
* Services.
*
* @return true if credential of the user currently logged in are used
*/
public boolean getUseDefaultCredentials() {
return this.useDefaultCredentials;
}
/**
* Sets a value indicating whether the credential of the user currently
* logged into Windows should be used to authenticate with the Exchange Web
* Services. Setting UseDefaultCredentials to true automatically sets the
* Credentials property to null.
*
* @param value the new use default credential
*/
public void setUseDefaultCredentials(boolean value) {
this.useDefaultCredentials = value;
if (value) {
this.credentials = null;
}
// Reset the httpContext, to remove any existing authentication cookies from subsequent request
initializeHttpContext();
}
/**
* Gets the timeout used when sending HTTP request and when receiving HTTP
* response, in milliseconds.
*
* @return timeout in milliseconds
*/
public int getTimeout() {
return timeout;
}
/**
* Sets the timeout used when sending HTTP request and when receiving HTTP
* respones, in milliseconds. Defaults to 100000.
*
* @param timeout timeout in milliseconds
*/
public void setTimeout(int timeout) {
if (timeout < 1) {
throw new IllegalArgumentException("Timeout must be greater than zero.");
}
this.timeout = timeout;
}
/**
* Gets a value that indicates whether HTTP pre-authentication should be
* performed.
*
* @return true indicates pre-authentication is set
*/
public boolean isPreAuthenticate() {
return preAuthenticate;
}
/**
* Sets a value that indicates whether HTTP pre-authentication should be
* performed.
*
* @param preAuthenticate true to enable pre-authentication
*/
public void setPreAuthenticate(boolean preAuthenticate) {
this.preAuthenticate = preAuthenticate;
}
/**
* Gets a value indicating whether GZip compression encoding should be
* accepted. This value will tell the server that the client is able to
* handle GZip compression encoding. The server will only send Gzip
* compressed content if it has been configured to do so.
*
* @return true if compression is used
*/
public boolean getAcceptGzipEncoding() {
return acceptGzipEncoding;
}
/**
* Gets a value indicating whether GZip compression encoding should
* be accepted. This value will tell the server that the client is able to
* handle GZip compression encoding. The server will only send Gzip
* compressed content if it has been configured to do so.
*
* @param acceptGzipEncoding true to enable compression
*/
public void setAcceptGzipEncoding(boolean acceptGzipEncoding) {
this.acceptGzipEncoding = acceptGzipEncoding;
}
/**
* Gets the requested server version.
*
* @return The requested server version.
*/
public ExchangeVersion getRequestedServerVersion() {
return this.requestedServerVersion;
}
/**
* Gets the user agent.
*
* @return The user agent.
*/
public String getUserAgent() {
return this.userAgent;
}
/**
* Sets the user agent.
*
* @param userAgent The user agent
*/
public void setUserAgent(String userAgent) {
this.userAgent = userAgent + " (" + ExchangeServiceBase.defaultUserAgent + ")";
}
/**
* Gets information associated with the server that processed the last
* request. Will be null if no request have been processed.
*
* @return the server info
*/
public ExchangeServerInfo getServerInfo() {
return serverInfo;
}
/**
* Sets information associated with the server that processed the last
* request.
*
* @param serverInfo Server Information
*/
public void setServerInfo(ExchangeServerInfo serverInfo) {
this.serverInfo = serverInfo;
}
/**
* Gets the web proxy that should be used when sending request to EWS.
*
* @return Proxy
* the Proxy Information
*/
public WebProxy getWebProxy() {
return this.webProxy;
}
/**
* Sets the web proxy that should be used when sending request to EWS.
* Set this property to null to use the default web proxy.
*
* @param value the Proxy Information
*/
public void setWebProxy(WebProxy value) {
this.webProxy = value;
}
/**
* Gets a collection of HTTP headers that will be sent with each request to
* EWS.
*
* @return httpHeaders
*/
public Map getHttpHeaders() {
return this.httpHeaders;
}
// Events
/**
* Provides an event that applications can implement to emit custom SOAP
* headers in request that are sent to Exchange.
*/
private List OnSerializeCustomSoapHeaders;
/**
* Gets the on serialize custom soap headers.
*
* @return the on serialize custom soap headers
*/
public List getOnSerializeCustomSoapHeaders() {
return OnSerializeCustomSoapHeaders;
}
/**
* Sets the on serialize custom soap headers.
*
* @param onSerializeCustomSoapHeaders the new on serialize custom soap headers
*/
public void setOnSerializeCustomSoapHeaders(List onSerializeCustomSoapHeaders) {
OnSerializeCustomSoapHeaders = onSerializeCustomSoapHeaders;
}
/**
* Traces the HTTP response headers.
*
* @param traceType kind of trace entry
* @param request The request
* @throws EWSHttpException EWS http exception
* @throws IOException signals that an I/O exception has occurred
* @throws XMLStreamException the XML stream exception
*/
public void processHttpResponseHeaders(TraceFlags traceType, HttpWebRequest request)
throws XMLStreamException, IOException, EWSHttpException {
this.traceHttpResponseHeaders(traceType, request);
this.saveHttpResponseHeaders(request.getResponseHeaders());
}
/**
* Save the HTTP response headers.
*
* @param headers The response headers
*/
private void saveHttpResponseHeaders(Map headers) {
this.httpResponseHeaders.clear();
for (String key : headers.keySet()) {
this.httpResponseHeaders.put(key, headers.get(key));
}
}
/**
* Gets a collection of HTTP headers from the last response.
* @return HTTP response headers
*/
public Map getHttpResponseHeaders() {
return this.httpResponseHeaders;
}
/**
* Gets the session key.
* @return session key
*/
public static byte[] getSessionKey() {
// this has to be computed only once.
synchronized (ExchangeServiceBase.class) {
if (ExchangeServiceBase.binarySecret == null) {
Random randomNumberGenerator = new Random();
ExchangeServiceBase.binarySecret = new byte[256 / 8];
randomNumberGenerator.nextBytes(binarySecret);
}
return ExchangeServiceBase.binarySecret;
}
}
public int getMaximumPoolingConnections() {
return maximumPoolingConnections;
}
}