namespace ChadSoft.Utils.Pingy
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Xml;
using Logging;
using Pingers;
///
/// Helper class to ease dealing with sets of pingers.
///
public class PingManager
{
#region Properties
private PingerCollection _Pingers;
///
/// Gets the list of pingers that we're managing.
///
/// The pingers.
public PingerCollection Pingers
{
get
{
if (_Pingers == null)
_Pingers = new PingerCollection();
return _Pingers;
}
}
private Dictionary _PingerStates = new Dictionary();
public Dictionary PingerStates
{
get { return _PingerStates; }
}
#endregion
#region Add Pinger
///
/// Adds the specified pinger to the current list of pingers
///
/// The pinger to be added.
public void Add(IPinger pinger)
{
Pingers.Add(pinger);
}
#endregion
#region PingAll
///
/// Pings all the registered pingers.
///
public void PingAll()
{
foreach (IPinger pinger in Pingers)
if (pinger != null)
PingerStates[pinger] = pinger.Ping();
}
#endregion
#region LoadFromXml
///
/// Loads a list of pingers from XML.
///
/// The path of the file containing the XML to be loaded.
/// The success of the pinger loading
///
/// TODO: This should probably be moved to a separate class...
/// The format of the XML should be:
/// <PingerCollection>
/// <Pinger Type="<Pinger Type>" [Path="<Path to Ping>"]>[ Pinger Info ]</Pinger>
/// </PingerCollection>
///
public bool LoadFromXml(string path)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException(path);
bool success = false;
Logger.Info("Loading Pingers from XML file {0}...", path);
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(path);
success = LoadFromXml(xmlDoc);
}
catch (Exception ex)
{
Logger.Debug("Exception during Pinger load: {0}", ex.Message);
ExceptionPolicy.NotCritical(ex);
}
Logger.Info("Finished loading pingers from {0}.", path);
return success;
}
///
/// Loads a list of pingers from XML.
///
/// The Stream containing the XML to be loaded.
/// The success of the pinger loading
///
/// TODO: This should probably be moved to a separate class...
/// The format of the XML should be:
/// <PingerCollection>
/// <Pinger Type="<Pinger Type>" [Path="<Path to Ping>"]>[ Pinger Info ]</Pinger>
/// </PingerCollection>
///
public bool LoadFromXml(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
bool success = false;
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(stream);
success = LoadFromXml(xmlDoc);
}
catch (Exception ex)
{
Logger.Debug("Exception during Pinger load: {0}", ex.Message);
ExceptionPolicy.NotCritical(ex);
}
return success;
}
///
/// Loads a list of pingers from an XmlDocument.
///
/// The XmlDocument containing the Pinger nodes.
/// The success of the pinger loading
///
/// TODO: This should probably be moved to a separate class...
/// The format of the XML should be:
/// <PingerCollection>
/// <Pinger Type="<Pinger Type>" [Path="<Path to Ping>"]>[ Pinger Info ]</Pinger>
/// </PingerCollection>
///
public bool LoadFromXml(XmlDocument pingersDoc)
{
if (pingersDoc == null)
throw new ArgumentNullException("pingersDoc");
bool success = false;
// TODO: Load Pingers of other types from this doc
try
{
foreach (XmlNode pingerNode in pingersDoc.GetElementsByTagName("Pinger"))
{
Logger.Debug("Parsing pinger node {0}", pingerNode);
string pingerPath = pingerNode.Attributes["Path"].Value;
Logger.Debug("Adding new UriPinger for Path {0}", pingerPath);
Add(Create(pingerPath));
}
success = true;
Logger.Debug("Loaded {0} Pingers.", Pingers.Count);
}
catch (Exception ex)
{
Logger.Error(ex);
ExceptionPolicy.Unhandled(ex);
}
return success;
}
#endregion
#region LoadFromWeb
///
/// Loads the list of Pingers from the links scrubbed from a webpage.
///
/// The webpage.
/// Success of operation
public bool LoadFromWeb(string webpage)
{
bool success = false;
HttpWebRequest request = WebRequest.Create(webpage) as HttpWebRequest;
request.UserAgent = "HttpWebRequest";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string content = reader.ReadToEnd();
MatchCollection links = Regex.Matches(
content,
"href=['\"](\\w+://[^'\"]*)['\"]",
RegexOptions.Multiline & RegexOptions.IgnoreCase);
foreach (Match link in links)
{
Add(Create(new Uri(link.Groups[1].Value)));
}
success = true;
}
}
return success;
}
#endregion
#region Create
public static IPinger Create(string path)
{
if (String.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
return Create(new Uri(path));
}
public static IPinger Create(Uri location)
{
if (location == null)
throw new ArgumentNullException("location");
if (location.IsFile || location.IsUnc)
return new FilePinger(location);
else
return new HttpPinger(location);
}
#endregion
}
}