using System; using System.IO; using System.Net; using System.Text; using System.Xml; namespace SharpMap.Web.Wcs { /// /// Web Coverage Service Client class /// public class Client : IClient { private XmlNamespaceManager _nsmgr; #region WCS Data structures #endregion #region Properties private string _version; private XmlDocument _xmlDoc; private string _baseUrl; private string _capabilitiesUrl; private IWebProxy _proxy; private int _timeOut; private ICredentials _credentials; private string[] _exceptionFormats; //private XmlNode _vendorSpecificCapabilities; /// /// Exposes the capabilities' VendorSpecificCapabilities as XmlNode object. External modules /// could use this to parse the vendor specific capabilities for their specific purpose. /// public XmlNode VendorSpecificCapabilities { get { return null;// _vendorSpecificCapabilities; } } /// /// Timeout of in milliseconds. Defaults to 10 seconds /// public int TimeOut { get { return _timeOut; } set { _timeOut = value; } } /// /// Gets or sets the credentials used to access the Web coverage service /// public ICredentials Credentials { get { return _credentials; } set { _credentials = value; } } /// /// Gets or sets the proxy used to establish the connection to the web coverage service /// public IWebProxy Proxy { get { return _proxy; } set { _proxy = value; } } /// /// Gets or sets the base URL for the server without any OGC specific name=value pairs /// public string BaseUrl { get { return _baseUrl; } set { _baseUrl = value; _capabilitiesUrl = CreateCapabilitiesUrl(_baseUrl); } } /// /// Gets the entire XML document as text /// public string CapabilitiesUrl { get { return _capabilitiesUrl; } } /// /// Gets the entire XML document as text /// public string GetXmlAsText { get { using (var sw = new StringWriter()) { var xw = new XmlTextWriter(sw); XmlDoc.WriteTo(xw); return sw.ToString(); } } } /// /// Gets the entire XML document as byte[] /// public byte[] GetXmlAsByteArray { get { using (var sw = new StringWriter()) { var xw = new XmlTextWriter(sw); XmlDoc.WriteTo(xw); var baData = Encoding.UTF8.GetBytes(sw.ToString()); return baData; } } } /// /// Gets the version of the WCS server (ex. "1.0.0") /// public string Version { get { return _version; } set { _version = value; } } /// /// Gets a list of available exception mime type formats /// public string[] ExceptionFormats { get { return _exceptionFormats; } } /// /// Gets the full capabilities xml document /// public XmlDocument XmlDoc { get { return _xmlDoc; } } #endregion #region Constructors /// /// Just instantiate, no parameters /// public Client() { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server public Client(string url) : this(url, null, 10000, null, "") { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server /// Proxy to use public Client(string url, IWebProxy proxy) : this(url, proxy, 10000, null, "") { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server /// Proxy to use /// public Client(string url, IWebProxy proxy, int timeOut) : this(url, proxy, timeOut, null, "") { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server /// Proxy to use /// Credentials for authenticating against remote WCS-server public Client(string url, IWebProxy proxy, ICredentials credentials) : this(url, proxy, 10000, credentials, "") { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server /// Proxy to use /// Web request timeout /// Credentials for authenticating against remote WCS-server public Client(string url, IWebProxy proxy, int timeOut, ICredentials credentials) : this(url, proxy, timeOut, credentials, "") { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server /// Proxy to use /// Web request timeout /// public Client(string url, IWebProxy proxy, int timeOut, string version) : this(url, proxy, timeOut, null, version) { } /// /// Initializes client to WCS server and parses the Capabilities request /// /// URL of wcs server /// Proxy to use /// Web request timeout /// /// public Client(string url, IWebProxy proxy, int timeOut, ICredentials credentials, string version) { _baseUrl = url; _proxy = proxy; _timeOut = timeOut; _version = version; _credentials = credentials; _capabilitiesUrl = CreateCapabilitiesUrl(url); _xmlDoc = GetRemoteXml(); ParseVersion(); ParseCapabilities(); } /// /// Hydrates Client object based on byte array version of XML document /// /// byte array version of capabilities document public Client(byte[] byteXml) { using (var stream = new MemoryStream(byteXml)) { var r = new XmlTextReader(stream); r.XmlResolver = null; _xmlDoc = new XmlDocument(); XmlDoc.XmlResolver = null; XmlDoc.Load(r); } _nsmgr = new XmlNamespaceManager(XmlDoc.NameTable); _baseUrl = ""; _proxy = null; _timeOut = 10000; _version = ""; _credentials = null; ParseVersion(); ParseCapabilities(); } #endregion #region Methods /// /// Function to create a Capabilities Url /// /// The base url /// A capabilities url public string CreateCapabilitiesUrl(string url) { var strReq = new StringBuilder(url); if (!url.Contains("?")) strReq.Append("?"); if (!strReq.ToString().EndsWith("&") && !strReq.ToString().EndsWith("?")) strReq.Append("&"); if (!url.ToLower().Contains("service=wcs")) strReq.AppendFormat("SERVICE=WCS&"); if (!url.ToLower().Contains("request=getcapabilities")) strReq.AppendFormat("REQUEST=GetCapabilities&"); if (_version != "") strReq.AppendFormat("VERSION=" + _version + "&"); return strReq.ToString(); } /// /// Parses a GetCapabilities request from an XMLDoc /// public void ParseCapabilities() { if (_xmlDoc == null) { throw (new ApplicationException("A valid WCS capabilities XML file was not loaded!")); } throw new NotImplementedException(); } /// /// Downloads servicedescription from WCS service /// /// XmlDocument from Url. Null if Url is empty or inproper XmlDocument public XmlDocument GetRemoteXml() { Stream stream; try { var myRequest = WebRequest.Create(_capabilitiesUrl); myRequest.Timeout = _timeOut; if (_proxy != null) myRequest.Proxy = _proxy; using (var myResponse = myRequest.GetResponse()) { stream = myResponse.GetResponseStream(); } if (stream == null) throw new ApplicationException("No response stream"); } catch (Exception ex) { throw new ApplicationException("Could not download capabilities document from the server. The server may not be available right now." + ex.Message); } try { using (var xmlTextReader = new XmlTextReader(_capabilitiesUrl, stream)) { xmlTextReader.XmlResolver = null; _xmlDoc = new XmlDocument(); _xmlDoc.XmlResolver = null; _xmlDoc.Load(xmlTextReader); _nsmgr = new XmlNamespaceManager(_xmlDoc.NameTable); } return _xmlDoc; } catch (Exception /*ex*/) { throw new ApplicationException("Could not convert the capabilities file into an XML document. Do you have illegal characters in the document."); } finally { stream.Close(); } } /// /// Parse the version number from the capabilities document /// public void ParseVersion() { if (XmlDoc.DocumentElement.Attributes["version"] != null) { _version = XmlDoc.DocumentElement.Attributes["version"].Value; if (_version != "1.0.0" && _version != "1.1.1") throw new ApplicationException("WCS Version " + _version + " is not currently supported"); } else throw (new ApplicationException("No service version number was found in the WCS capabilities XML file!")); } /// /// Parses valid exceptions /// /// private void ParseExceptions(XmlNode xnlExceptionNode) { XmlNodeList xnlFormats = xnlExceptionNode.SelectNodes("sm:Format", _nsmgr); if (xnlFormats != null) { _exceptionFormats = new string[xnlFormats.Count]; for (int i = 0; i < xnlFormats.Count; i++) { _exceptionFormats[i] = xnlFormats[i].InnerText; } } } /// /// Method to validate the web server's response /// public void ValidateXml() { throw new NotImplementedException(); } #endregion } }