using System;
using System.Xml;
using System.Diagnostics;
using System.ComponentModel;
namespace AnticipatingMinds.Genesis.KnowledgeManagement{
/// <summary>
/// Represents a user profile.
/// </summary>
/// <remarks>
/// Profile is a way to group rules.
/// User can create multiple profiles and add rule intances into it.
/// </remarks>
public class Profile
{
/// <summary>
/// Represnts a delegate to handle an event of profile properties being changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes new instance of the <see cref="Profile"/> class.
/// </summary>
/// <param name="knowledgeBase">Knowledgebase whenre profile shaould be created.</param>
public Profile(KnowledgeBase knowledgeBase):this(new XmlDocument().CreateElement("profile"),knowledgeBase)
{
id = Guid.NewGuid().ToString();
}
internal Profile(XmlElement profileXmlElement,KnowledgeBase knowledgeBase)
{
if(profileXmlElement == null)
return;
id = profileXmlElement.GetAttribute("id");
parentId = profileXmlElement.GetAttribute("parent_id");
name = profileXmlElement["name"] == null ? string.Empty : profileXmlElement["name"].InnerText;
description = profileXmlElement["description"] == null ? string.Empty : profileXmlElement["description"].InnerText;
helpUrl = profileXmlElement["help_url"] == null ? string.Empty : profileXmlElement["help_url"].InnerText;
profileXml = profileXmlElement;
this.knowledgeBase = knowledgeBase;
}
/// <summary>
/// Gets profile id.
/// </summary>
[BrowsableAttribute(false)]
public virtual string Id
{
get
{
return id;
}
}
/// <summary>
/// Gets or sets parent profile id.
/// </summary>
[BrowsableAttribute(false)]
public virtual string ParentId
{
get
{
return parentId;
}
set
{
if(value != null && value.Length != 0)
{
Profile newParentProfile = knowledgeBase.GetProfileById(value);
if(newParentProfile == null)
{
Debug.Assert(newParentProfile != null,"How?");
return;
}
if(newParentProfile.IsDescendantOf(id))
throw new RecursiveParentChildRelationshipException();
}
parentId = value == null ? string.Empty : value;
profileXml.SetAttribute("parent_id",parentId);
OnPropertyChanged("ParentId");
}
}
/// <summary>
/// Gets or sets profile name.
/// </summary>
[CategoryAttribute("Appearance")]
public virtual string Name
{
get
{
return name;
}
set
{
name = value == null ? string.Empty : value;
if(profileXml["name"] == null)
profileXml.AppendChild(profileXml.OwnerDocument.CreateElement("name"));
profileXml["name"].InnerText = name;
OnPropertyChanged("Name");
}
}
/// <summary>
/// Gets or sets profile description.
/// </summary>
[CategoryAttribute("Misc")]
public virtual string Description
{
get
{
return description;
}
set
{
description = value == null ? string.Empty : value;
if(profileXml["description"] == null)
profileXml.AppendChild(profileXml.OwnerDocument.CreateElement("description"));
profileXml["description"].InnerText = description;
OnPropertyChanged("Description");
}
}
/// <summary>
/// Gets or sets profile help url.
/// </summary>
[CategoryAttribute("Misc")]
public virtual string HelpUrl
{
get
{
return helpUrl;
}
set
{
helpUrl = value == null ? string.Empty : value;
if(profileXml["help_url"] == null)
profileXml.AppendChild(profileXml.OwnerDocument.CreateElement("help_url"));
profileXml["help_url"].InnerText = helpUrl;
OnPropertyChanged("HelpUrl");
}
}
/// <summary>
/// Adds a new rule to a profile.
/// </summary>
/// <param name="ruleId">Id of the rule to add.</param>
public virtual void AddRule(string ruleId)
{
XmlNode ruleNode = profileXml.SelectSingleNode("rule[. = '" + ruleId + "']");
if(ruleNode != null)
return;
profileXml.AppendChild(profileXml.OwnerDocument.CreateElement("rule")).InnerText = ruleId;
OnPropertyChanged("rule");
}
/// <summary>
/// Removes rule from profile.
/// </summary>
/// <param name="ruleId">Id of the rule to remove.</param>
public virtual void RemoveRule(string ruleId)
{
XmlNode ruleNode = profileXml.SelectSingleNode("rule[. = '" + ruleId + "']");
if(ruleNode == null)
return;
profileXml.RemoveChild(ruleNode);
OnPropertyChanged("rule");
}
/// <summary>
/// This member is for internal use only.
/// </summary>
[BrowsableAttribute(false)]
public virtual string[] Rules
{
get
{
XmlNodeList Nodes = profileXml.SelectNodes("rule");
string[] Ids = new string[Nodes.Count];
int Index = 0;
foreach(XmlNode Node in Nodes)
{
Ids[Index++] = Node.InnerText;
}
return Ids;
}
}
/// <summary>
/// This member is for internal use only.
/// </summary>
public virtual void ClearRules()
{
XmlNodeList Nodes = profileXml.SelectNodes("rule");
foreach(XmlNode node in Nodes)
{
profileXml.RemoveChild(node);
}
OnPropertyChanged("rule");
}
/// <summary>
/// This member is for internal use only.
/// </summary>
/// <param name="propertyName"></param>
protected virtual void OnPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// This member is for internal use only.
/// </summary>
/// <param name="parentProfileId"></param>
/// <returns></returns>
public bool IsDescendantOf(string parentProfileId)
{
if(parentProfileId == id)
return true;
if(parentProfileId.Length == 0)
return false;
if(ParentId.Length == 0)
return false;
Profile parentProfile = knowledgeBase.GetProfileById(ParentId);
if(parentProfile.ParentId.Length == 0)
return false;
if(parentProfile.Id == parentProfileId)
return true;
return parentProfile.IsDescendantOf(parentProfileId);
}
/// <summary>
/// This member is for internal use only.
/// </summary>
/// <returns></returns>
public XmlElement GetProfileXml()
{
return profileXml;
}
private string id;
private string parentId = string.Empty;
private string name;
private string description;
private string helpUrl;
private XmlElement profileXml;
private KnowledgeBase knowledgeBase;
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
public class AllRulesProfile : Profile
{
internal AllRulesProfile(KnowledgeBase knowledgeBase):base(null,knowledgeBase)
{
this.knowledgeBase = knowledgeBase;
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
[BrowsableAttribute(false)]
public override string Id
{
get
{
return knowledgeBase.AllRulesProfileId;
}
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
[BrowsableAttribute(false)]
public override string ParentId
{
get
{
return string.Empty;
}
set
{
}
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
[CategoryAttribute("Appearance")]
public override string Name
{
get
{
return "All Rules";
}
set
{
}
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
[CategoryAttribute("Misc")]
public override string Description
{
get
{
return "All rules in Knowledge Base";
}
set
{
}
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
[CategoryAttribute("Misc")]
public override string HelpUrl
{
get
{
return "http://help.anticipatingminds.com/codementor/v1.0/profiles/allrulesprofile.html";
}
set
{
}
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
[BrowsableAttribute(false)]
public override string[] Rules
{
get
{
return knowledgeBase.RuleIds;
}
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
/// <param name="ruleId"></param>
public override void AddRule(string ruleId)
{
}
/// <summary>
/// This class is intended for internal use only.
/// </summary>
/// <param name="ruleId"></param>
public override void RemoveRule(string ruleId)
{
}
private KnowledgeBase knowledgeBase;
}
}
|