All Downloads are FREE. Search and download functionalities are using the official Maven repository.

microsoft.exchange.webservices.data.AutodiscoverRequest Maven / Gradle / Ivy

Go to download

The source came from http://archive.msdn.microsoft.com/ewsjavaapi Support for Maven has been added.

There is a newer version: 1.1.5.2
Show newest version
/**************************************************************************
 * copyright file="AutodiscoverRequest.java" company="Microsoft"
 *     Copyright (c) Microsoft Corporation.  All rights reserved.
 * 
 * Defines the AutodiscoverRequest.java.
 **************************************************************************/
package microsoft.exchange.webservices.data;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import javax.xml.stream.XMLStreamException;

/***
 * Represents the base class for all requested made to the Autodiscover service.
 * 
 */
abstract class AutodiscoverRequest {

	/** The service. */
	private AutodiscoverService service;

	/** The url. */
	private URI url;

	/***
	 * Initializes a new instance of the AutodiscoverResponse class.
	 * 
	 * @param service
	 *            Autodiscover service associated with this request.
	 * @param url
	 *            URL of Autodiscover service.
	 * 
	 */
	protected AutodiscoverRequest(AutodiscoverService service, URI url) {
		this.service = service;
		this.url = url;
	}
    
    /**
	 * * Determines whether response is a redirection.
	 * 
	 * @param request
	 *            the request
	 * @return True if redirection response.
	 * @throws EWSHttpException
	 *             the eWS http exception
	 */
	protected static boolean isRedirectionResponse(HttpWebRequest request)
			throws EWSHttpException {
		return ((request.getResponseCode() == 301)
				|| (request.getResponseCode() == 302)
				|| (request.getResponseCode() == 307) || (request
				.getResponseCode() == 303));
	}
	
	/**
	 * * Validates the request.
	 * 
	 * @throws ServiceLocalException
	 *             the service local exception
	 * @throws Exception
	 *             the exception
	 */
	protected void validate() throws ServiceLocalException, Exception {
		this.getService().validate();
	}

	/**
	 * * Executes this instance.
	 * 
	 * @return the autodiscover response
	 * @throws ServiceLocalException
	 *             the service local exception
	 * @throws Exception
	 *             the exception
	 */
	protected AutodiscoverResponse internalExecute()
			throws ServiceLocalException, Exception {
		this.validate();
		HttpWebRequest request = null;
		try {
			request = this.service.prepareHttpWebRequestForUrl(this.url);
			this.service.traceHttpRequestHeaders(
			TraceFlags.AutodiscoverRequestHttpHeaders, request);

			OutputStream urlOutStream = request.getOutputStream();
			// OutputStreamWriter out = new OutputStreamWriter(request
			// .getOutputStream());

			ByteArrayOutputStream memoryStream = new ByteArrayOutputStream();
			this.writeSoapRequest(this.url, memoryStream);

			if (this.service.isTraceEnabledFor(TraceFlags.AutodiscoverRequest)) {
				memoryStream.flush();
				this.service.traceXml(TraceFlags.AutodiscoverRequest,
						memoryStream);
			}
			memoryStream.writeTo(urlOutStream);
			urlOutStream.flush();
			urlOutStream.close();
			memoryStream.close();
			// out.write(memoryStream.toString());
			// out.close();
			request.executeRequest();
			request.getResponseCode();
			if (AutodiscoverRequest.isRedirectionResponse(request)) {
				AutodiscoverResponse response = this
						.createRedirectionResponse(request);
				if (response != null) {
					return response;
				} else {
					throw new ServiceRemoteException(
							Strings.InvalidRedirectionResponseReturned);
				}
			}

			/*
			 * BufferedReader in = new BufferedReader(new
			 * InputStreamReader(request.getInputStream()));
			 * 
			 * String decodedString;
			 * 
			 * while ((decodedString = in.readLine()) != null) {
			 * System.out.println(decodedString); } in.close();
			 */

			memoryStream = new ByteArrayOutputStream();
			InputStream serviceResponseStream = request.getInputStream();

			while (true) {
				int data = serviceResponseStream.read();
				if (-1 == data) {
					break;
				} else {
					memoryStream.write(data);
				}
			}
			memoryStream.flush();
			serviceResponseStream.close();

			if (this.service.isTraceEnabled()) {
				this.service.traceResponse(request, memoryStream);
			}
			ByteArrayInputStream memoryStreamIn = new ByteArrayInputStream(
					memoryStream.toByteArray());
			EwsXmlReader ewsXmlReader = new EwsXmlReader(memoryStreamIn);

			// WCF may not generate an XML declaration.
			ewsXmlReader.read();
			if (ewsXmlReader.getNodeType().getNodeType() == XMLNodeType.START_DOCUMENT) {
				ewsXmlReader.readStartElement(XmlNamespace.Soap,
						XmlElementNames.SOAPEnvelopeElementName);
			} else if ((ewsXmlReader.getNodeType().getNodeType() != XMLNodeType.START_ELEMENT)
					|| (!ewsXmlReader.getLocalName().equals(
							XmlElementNames.SOAPEnvelopeElementName))
					|| (!ewsXmlReader.getNamespaceUri().equals(
							EwsUtilities.getNamespaceUri(XmlNamespace.Soap)))) {
				throw new ServiceXmlDeserializationException(
						Strings.InvalidAutodiscoverServiceResponse);
			}

			this.readSoapHeader(ewsXmlReader);

			AutodiscoverResponse response = this.readSoapBody(ewsXmlReader);

			ewsXmlReader.readEndElement(XmlNamespace.Soap,
					XmlElementNames.SOAPEnvelopeElementName);

			if (response.getErrorCode() == AutodiscoverErrorCode.NoError) {
				return response;
			} else {
				throw new AutodiscoverResponseException(
						response.getErrorCode(), response.getErrorMessage());
			}

		} catch (XMLStreamException ex) {
			this.service.traceMessage(TraceFlags.AutodiscoverConfiguration,
					String.format("XML parsing error: %s", ex.getMessage()));

			// Wrap exception
			throw new ServiceRequestException(String.format(
					Strings.ServiceRequestFailed, ex.getMessage()), ex);
		} catch (IOException ex)
        {
            this.service.traceMessage(
                TraceFlags.AutodiscoverConfiguration,
                String.format("I/O error: %s", ex.getMessage()));

            // Wrap exception
            throw new ServiceRequestException(String.format(
					Strings.ServiceRequestFailed, ex.getMessage()), ex);
        } catch (Exception ex) {
			// HttpWebRequest httpWebResponse = (HttpWebRequest)ex;

			if (null != request && request.getResponseCode() == 7) {
				if (AutodiscoverRequest.isRedirectionResponse(request)) {
					this.service
							.traceHttpResponseHeaders(
									TraceFlags.AutodiscoverResponseHttpHeaders,
									request);

					AutodiscoverResponse response = this
							.createRedirectionResponse(request);
					if (response != null) {
						return response;
					}
				} else {
					this.processWebException(ex, request);
				}
			}

			// Wrap exception if the above code block didn't throw
			throw new ServiceRequestException(String.format(
					Strings.ServiceRequestFailed, ex.getMessage()), ex);
		} finally {
			try {
				request.close(); 
			} catch (Exception e2) {
				request = null;
			} 
		}

	}

	/***
	 * Processes the web exception.
	 * 
	 * @param exception
	 *            WebException
	 * @param req
	 *            HttpWebRequest
	 * 
	 */
	private void processWebException(Exception exception, HttpWebRequest req) {
		SoapFaultDetails soapFaultDetails = null;
		if (null != req) {
			try {
				if (500 == req.getResponseCode()) {
					if (this.service
							.isTraceEnabledFor(
									TraceFlags.AutodiscoverRequest)) {
						ByteArrayOutputStream memoryStream = 
							new ByteArrayOutputStream();
						InputStream serviceResponseStream = AutodiscoverRequest
								.getResponseStream(req);
						while (true) {
							int data = serviceResponseStream.read();
							if (-1 == data) {
								break;
							} else {
								memoryStream.write(data);
							}
						}
						memoryStream.flush();
						serviceResponseStream.close();
						this.service.traceResponse(req, memoryStream);
						ByteArrayInputStream memoryStreamIn = 
							new ByteArrayInputStream(
								memoryStream.toByteArray());
						EwsXmlReader reader = new EwsXmlReader(memoryStreamIn);
						//soapFaultDetails = this.readSoapFault(reader);
						this.readSoapFault(reader);
						memoryStream.close();
					} else {
						InputStream serviceResponseStream = AutodiscoverRequest
								.getResponseStream(req);
						EwsXmlReader reader = new EwsXmlReader(
								serviceResponseStream);
						soapFaultDetails = this.readSoapFault(reader);
						serviceResponseStream.close();

						if (soapFaultDetails != null) {
							throw new ServiceResponseException(
									new ServiceResponse(soapFaultDetails));
						}
					}
				} else {
					this.service.processHttpErrorResponse(req, exception);
	                
				}
			} catch (Exception e) {
				// do nothing
				e.printStackTrace();
			}
		}
	}

	/**
	 * * Create a redirection response.
	 * 
	 * @param httpWebResponse
	 *            The HTTP web response.
	 * @return AutodiscoverResponse autodiscoverResponse object.
	 * @throws XMLStreamException
	 *             the xML stream exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 * @throws EWSHttpException
	 *             the eWS http exception
	 */
	private AutodiscoverResponse createRedirectionResponse(
			HttpWebRequest httpWebResponse) throws XMLStreamException,
			IOException, EWSHttpException {
		String location = httpWebResponse.getResponseHeaderField("Location");
		if (!(location == null || location.isEmpty())) {
			try {
				URI redirectionUri = new URI(location);
				if (redirectionUri.getScheme().toLowerCase().equals("http")
						|| redirectionUri.getScheme().toLowerCase().equals(
								"https")) {
					AutodiscoverResponse response = this
							.createServiceResponse();
					response.setErrorCode(AutodiscoverErrorCode.RedirectUrl);
					response.setRedirectionUrl(redirectionUri);
					return response;
				}

				this.service
						.traceMessage(
								TraceFlags.AutodiscoverConfiguration,
								String
										.format(
												"Invalid redirection" +
												" URL '%s' " +
												"returned by Autodiscover " +
												"service.",
												redirectionUri.toString()));

			} catch (URISyntaxException ex) {
				this.service
						.traceMessage(
								TraceFlags.AutodiscoverConfiguration,
								String
										.format(
												"Invalid redirection " +
												"location '%s' " +
												"returned by Autodiscover " +
												"service.",
												location));
			}
		} else {
			this.service
					.traceMessage(
							TraceFlags.AutodiscoverConfiguration,
							"Redirection response returned by Autodiscover " +
							"service without redirection location.");
		}

		return null;
	}

	/***
	 * Reads the SOAP fault.
	 * 
	 * @param reader
	 *            The reader.
	 * @return SOAP fault details.
	 * 
	 */
	private SoapFaultDetails readSoapFault(EwsXmlReader reader) {
		SoapFaultDetails soapFaultDetails = null;

		try {

			reader.read();
			if (reader.getNodeType().getNodeType() == XMLNodeType.START_DOCUMENT) {
				reader.read();
			}
			if (!reader.isStartElement()
					|| (!reader.getLocalName().equals(
							XmlElementNames.SOAPEnvelopeElementName))) {
				return soapFaultDetails;
			}

			// Get the namespace URI from the envelope element and use it for
			// the rest of the parsing.
			// If it's not 1.1 or 1.2, we can't continue.
			XmlNamespace soapNamespace = EwsUtilities
					.getNamespaceFromUri(reader.getNamespaceUri());
			if (soapNamespace == XmlNamespace.NotSpecified) {
				return soapFaultDetails;
			}

			reader.read();

			// Skip SOAP header.
			if (reader.isStartElement(soapNamespace,
					XmlElementNames.SOAPHeaderElementName)) {
				do {
					reader.read();
				} while (!reader.isEndElement(soapNamespace,
						XmlElementNames.SOAPHeaderElementName));

				// Queue up the next read
				reader.read();
			}

			// Parse the fault element contained within the SOAP body.
			if (reader.isStartElement(soapNamespace,
					XmlElementNames.SOAPBodyElementName)) {
				do {
					reader.read();

					// Parse Fault element
					if (reader.isStartElement(soapNamespace,
							XmlElementNames.SOAPFaultElementName)) {
						soapFaultDetails = SoapFaultDetails.parse(reader,
								soapNamespace);
					}
				} while (!reader.isEndElement(soapNamespace,
						XmlElementNames.SOAPBodyElementName));
			}

			reader.readEndElement(soapNamespace,
					XmlElementNames.SOAPEnvelopeElementName);
		} catch (Exception e) {
			// If response doesn't contain a valid SOAP fault, just ignore
			// exception and
			// return null for SOAP fault details.
			e.printStackTrace();
		}

		return soapFaultDetails;
	}

	/**
	 * * Writes the autodiscover SOAP request.
	 * 
	 * @param requestUrl
	 *            Request URL.
	 * @param memoryStream
	 *            the memory stream
	 * @return stream The stream.
	 * @throws XMLStreamException
	 *             the xML stream exception
	 * @throws ServiceXmlSerializationException
	 *             the service xml serialization exception
	 */
	protected void writeSoapRequest(URI requestUrl,
			ByteArrayOutputStream memoryStream) throws XMLStreamException,
			ServiceXmlSerializationException {
		EwsServiceXmlWriter writer = new EwsServiceXmlWriter(this.service,
				memoryStream);
		writer.writeStartDocument();
		writer.writeStartElement(XmlNamespace.Soap,
				XmlElementNames.SOAPEnvelopeElementName);
		writer.writeAttributeValue("xmlns", EwsUtilities
				.getNamespacePrefix(XmlNamespace.Soap), EwsUtilities
				.getNamespaceUri(XmlNamespace.Soap));
		writer.writeAttributeValue("xmlns",
				EwsUtilities.AutodiscoverSoapNamespacePrefix,
				EwsUtilities.AutodiscoverSoapNamespace);
		writer.writeAttributeValue("xmlns",
				EwsUtilities.WSAddressingNamespacePrefix,
				EwsUtilities.WSAddressingNamespace);
		writer.writeAttributeValue("xmlns",
				EwsUtilities.EwsXmlSchemaInstanceNamespacePrefix,
				EwsUtilities.EwsXmlSchemaInstanceNamespace);

		writer.writeStartElement(XmlNamespace.Soap,
				XmlElementNames.SOAPHeaderElementName);

		if (this.service.getCredentials() != null) {
			this.service.getCredentials().emitExtraSoapHeaderNamespaceAliases(
					writer.getInternalWriter());
		}

		writer.writeElementValue(XmlNamespace.Autodiscover,
				XmlElementNames.RequestedServerVersion, this.service
						.getRequestedServerVersion().toString());

		writer.writeElementValue(XmlNamespace.WSAddressing,
				XmlElementNames.Action, this.getWsAddressingActionName());

		writer.writeElementValue(XmlNamespace.WSAddressing, XmlElementNames.To,
				requestUrl.toString());

		if (this.service.getCredentials() != null) {
			this.service.getCredentials().serializeWSSecurityHeaders(
					writer.getInternalWriter());
		}

		this.service.doOnSerializeCustomSoapHeaders(writer.getInternalWriter());

		writer.writeEndElement(); // soap:Header

		writer.writeStartElement(XmlNamespace.Soap,
				XmlElementNames.SOAPBodyElementName);

		this.writeBodyToXml(writer);

		writer.writeEndElement(); // soap:Body
		writer.writeEndElement(); // soap:Envelope
		writer.flush();
		writer.dispose();
	}

	/**
	 * * Writes XML body.
	 * 
	 * @param writer
	 *            The writer.
	 * @throws ServiceXmlSerializationException
	 *             the service xml serialization exception
	 * @throws XMLStreamException
	 *             the xML stream exception
	 */
	protected void writeBodyToXml(EwsServiceXmlWriter writer)
			throws ServiceXmlSerializationException, XMLStreamException {
		writer.writeStartElement(XmlNamespace.Autodiscover, this
				.getRequestXmlElementName());
		// writer.WriteAttributeValue("xmlns",
		// EwsUtilities.AutodiscoverSoapNamespacePrefix,
		// EwsUtilities.AutodiscoverSoapNamespace);

		this.writeAttributesToXml(writer);
		this.writeElementsToXml(writer);

		writer.writeEndElement(); // m:this.GetXmlElementName()
	}

	/**
	 * * Gets the response stream (may be wrapped with GZip/Deflate stream to
	 * decompress content).
	 * 
	 * @param request
	 *            the request
	 * @return ResponseStream
	 * @throws EWSHttpException
	 *             the eWS http exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	protected static InputStream getResponseStream(HttpWebRequest request)
			throws EWSHttpException, IOException {
		String contentEncoding = "";

		if (null != request.getContentEncoding()) {
			contentEncoding = request.getContentEncoding().toLowerCase();
		}

		InputStream responseStream;

		if (contentEncoding.contains("gzip")) {
			responseStream = new GZIPInputStream(request.getInputStream());
		} else if (contentEncoding.contains("deflate")) {
			responseStream = new InflaterInputStream(request.getInputStream());
		} else {
			responseStream = request.getInputStream();
		}
		return responseStream;
	}

	/**
	 * * Read SOAP header.
	 * 
	 * @param reader
	 *            EwsXmlReader.
	 * @throws Exception
	 *             the exception
	 */
	protected void readSoapHeader(EwsXmlReader reader) throws Exception {
		reader.readStartElement(XmlNamespace.Soap,
				XmlElementNames.SOAPHeaderElementName);
		do {
			reader.read();

			// Is this the ServerVersionInfo?
			if (reader.isStartElement(XmlNamespace.Autodiscover,
					XmlElementNames.ServerVersionInfo)) {
				this.service.setServerInfo(this.readServerVersionInfo(reader));
			}
		} while (!reader.isEndElement(XmlNamespace.Soap,
				XmlElementNames.SOAPHeaderElementName));
	}

	/**
	 * * Read ServerVersionInfo SOAP header.
	 * 
	 * @param reader
	 *            EwsXmlReader.
	 * @return ExchangeServerInfo ExchangeServerInfo object
	 * @throws Exception
	 *             the exception
	 */
	private ExchangeServerInfo readServerVersionInfo(EwsXmlReader reader)
			throws Exception {
		ExchangeServerInfo serverInfo = new ExchangeServerInfo();
		do {
			reader.read();

			if (reader.isStartElement()) {
				if (reader.getLocalName().equals(XmlElementNames.MajorVersion)) {
					serverInfo.setMajorVersion(reader
							.readElementValue(Integer.class));
				} else if (reader.getLocalName().equals(
						XmlElementNames.MinorVersion)) {
					serverInfo.setMinorVersion(reader
							.readElementValue(Integer.class));
				} else if (reader.getLocalName().equals(
						XmlElementNames.MajorBuildNumber)) {
					serverInfo.setMajorBuildNumber(reader
							.readElementValue(Integer.class));
				} else if (reader.getLocalName().equals(
						XmlElementNames.MinorBuildNumber)) {
					serverInfo.setMinorBuildNumber(reader
							.readElementValue(Integer.class));
				} else if (reader.getLocalName()
						.equals(XmlElementNames.Version)) {
					serverInfo.setVersionString(reader.readElementValue());
				}
			}
		} while (!reader.isEndElement(XmlNamespace.Autodiscover,
				XmlElementNames.ServerVersionInfo));

		return serverInfo;
	}

	/**
	 * * Read SOAP body.
	 * 
	 * @param reader
	 *            EwsXmlReader.
	 * @return AutodiscoverResponse AutodiscoverResponse object
	 * @throws InstantiationException
	 *             the instantiation exception
	 * @throws IllegalAccessException
	 *             the illegal access exception
	 * @throws ParseException
	 *             the parse exception
	 * @throws Exception
	 *             the exception
	 */
	protected AutodiscoverResponse readSoapBody(EwsXmlReader reader)
			throws InstantiationException, IllegalAccessException,
			ParseException, Exception {
		reader.readStartElement(XmlNamespace.Soap,
				XmlElementNames.SOAPBodyElementName);
		AutodiscoverResponse responses = this.loadFromXml(reader);
		reader.readEndElement(XmlNamespace.Soap,
				XmlElementNames.SOAPBodyElementName);
		return responses;
	}

	/**
	 * * Loads responses from XML.
	 * 
	 * @param reader
	 *            The reader.
	 * @return AutodiscoverResponse AutodiscoverResponse object
	 * @throws InstantiationException
	 *             the instantiation exception
	 * @throws IllegalAccessException
	 *             the illegal access exception
	 * @throws ParseException
	 *             the parse exception
	 * @throws Exception
	 *             the exception
	 */
	protected AutodiscoverResponse loadFromXml(EwsXmlReader reader)
			throws InstantiationException, IllegalAccessException,
			ParseException, Exception {
		String elementName = this.getResponseXmlElementName();
		reader.readStartElement(XmlNamespace.Autodiscover, elementName);
		AutodiscoverResponse response = this.createServiceResponse();
		response.loadFromXml(reader, elementName);
		return response;
	}

	/***
	 * Gets the name of the request XML element.
	 * 
	 * @return RequestXmlElementName gets XmlElementName.
	 * 
	 */
	protected abstract String getRequestXmlElementName();

	/***
	 * Gets the name of the response XML element.
	 * 
	 * @return ResponseXmlElementName gets XmlElementName.
	 * 
	 */
	protected abstract String getResponseXmlElementName();

	/***
	 * Gets the WS-Addressing action name.
	 * 
	 * @return WsAddressingActionName gets WsAddressingActionName.
	 * 
	 */
	protected abstract String getWsAddressingActionName();

	/***
	 * Creates the service response.
	 * 
	 * @return AutodiscoverResponse AutodiscoverResponse object.
	 * 
	 */
	protected abstract AutodiscoverResponse createServiceResponse();

	/**
	 * * Writes attributes to request XML.
	 * 
	 * @param writer
	 *            The writer.
	 * @throws ServiceXmlSerializationException
	 *             the service xml serialization exception
	 */
	protected abstract void writeAttributesToXml(EwsServiceXmlWriter writer)
			throws ServiceXmlSerializationException;

	/**
	 * * Writes elements to request XML.
	 * 
	 * @param writer
	 *            The writer.
	 * @throws XMLStreamException
	 *             the xML stream exception
	 * @throws ServiceXmlSerializationException
	 *             the service xml serialization exception
	 */
	protected abstract void writeElementsToXml(EwsServiceXmlWriter writer)
			throws XMLStreamException, ServiceXmlSerializationException;

	/**
	 * Gets the Service.
	 * 
	 * @return AutodiscoverService AutodiscoverService object.
	 * 
	 */
	protected AutodiscoverService getService() {
		return this.service;
	}

	/**
	 * Gets the URL.
	 * 
	 * @return url URL Object.
	 * 
	 */
	protected URI getUrl() {
		return this.url;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy