|
/***********************************************************************\
* Comnicate.CodeDom.Xml.ParserSchemas *
* Parses xml-based languages according to a user defined schema. *
* Copyright � 2005 Tomas Deml (as Comnicate!) *
* tomasdeml@msn.com *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
\***********************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace Comnicate.CodeDom.Xml.ParserSchemas.Rules.Evaluated
{
/// <summary>
/// Represents evaluated rule supporting the child rules evalution.
/// </summary>
public class EvaluatedParentalRule : EvaluatedRule, ILinkResolver
{
#region Fields
// Evaluated required children dictionary
private Dictionary<string, EvaluatedRule> requiredChildren;
// Evaluated optional children dictionary
private Dictionary<string, EvaluatedRule> optionalChildren;
// Aliased items
internal Dictionary<string, EvaluatedRule> LinkedEvaluatedRules;
// Default children lookup dictionary
private LookupLocation defaultChildLookupLocation;
// Cache for first optional child rule
private EvaluatedRule firstOptionalChildSingleton;
#endregion
#region Enums
/// <summary>
/// Specifies the default child rule lookup dictionary.
/// </summary>
public enum LookupLocation
{
/// <summary>
/// Lookup in the required children dictionary.
/// </summary>
RequiredChildren,
/// <summary>
/// Lookup in the optional children dictionary.
/// </summary>
OptionalChildren
}
#endregion
#region .ctors
/// <summary>
/// Initializes a new instance of the <see cref="EvaluatedParentalRule"/> class.
/// </summary>
/// <param name="rule">Original rule.</param>
public EvaluatedParentalRule(ParentalRule rule) : base(rule)
{
// Init collections
this.requiredChildren = new Dictionary<string, EvaluatedRule>(3);
this.optionalChildren = new Dictionary<string, EvaluatedRule>(3);
this.LinkedEvaluatedRules = new Dictionary<string, EvaluatedRule>(1);
// Set defaults
this.defaultChildLookupLocation = LookupLocation.RequiredChildren;
}
#endregion
#region Properties
/// <summary>
/// Gets the dictionary containing evaluated required child rules.
/// </summary>
public Dictionary<string, EvaluatedRule> RequiredChildren
{
get
{
return this.requiredChildren;
}
}
/// <summary>
/// Gets the dictionary containing evaluated optional child rules.
/// </summary>
public Dictionary<string, EvaluatedRule> OptionalChildren
{
get
{
return this.optionalChildren;
}
}
/// <summary>
/// Gets or sets the default child rules lookup dictionary.
/// </summary>
public LookupLocation DefaultChildLookupLocation
{
get
{
return this.defaultChildLookupLocation;
}
set
{
this.defaultChildLookupLocation = value;
}
}
/// <summary>
/// Gets the first optional child rule.
/// </summary>
public EvaluatedRule FirstOptionalChild
{
get
{
// If we didn't cached it and there are optional children...
if (this.firstOptionalChildSingleton == null && this.optionalChildren.Count > 0)
// Go through evaluated optional children and pick the first one...
foreach (EvaluatedRule rule in this.optionalChildren.Values)
{
this.firstOptionalChildSingleton = rule;
break;
}
// Return cached item
return this.firstOptionalChildSingleton;
}
}
#endregion
#region Methods
/// <summary>
/// Lookups the evaluated child rule by its name in the default lookup dictionary specified by the <see cref="DefaultChildLookupLocation"/> property.
/// </summary>
/// <param name="key">Child key.</param>
/// <returns>Evaluated child rule.</returns>
public EvaluatedRule LookupChild(string key)
{
return this.LookupChildAs<EvaluatedRule>(key, this.defaultChildLookupLocation);
}
/// <summary>
/// Lookups the evaluated child rule by its name in the specified lookup dictionary.
/// </summary>
/// <param name="key">Child key.</param>
/// <param name="location">Lookup dictionary.</param>
/// <returns>Evaluated child rule.</returns>
public EvaluatedRule LookupChild(string key, LookupLocation location)
{
return this.LookupChildAs<EvaluatedRule>(key, location);
}
/// <summary>
/// Lookups the evaluated child rule by its name in the default lookup dictionary specified by the <see cref="DefaultChildLookupLocation"/> property.
/// </summary>
/// <typeparam name="T">Child type.</typeparam>
/// <param name="key">Child key.</param>
/// <returns>Evaluated child rule.</returns>
public T LookupChildAs<T>(string key) where T : EvaluatedRule
{
return this.LookupChildAs<T>(key, this.defaultChildLookupLocation);
}
/// <summary>
/// Lookups the evaluated child rule by its name in the specified lookup dictionary.
/// </summary>
/// <typeparam name="T">Child type.</typeparam>
/// <param name="key">Child key.</param>
/// <param name="location">Lookup dictionary.</param>
/// <returns>Evaluated child rule.</returns>
public T LookupChildAs<T>(string key, LookupLocation location) where T : EvaluatedRule
{
// Choose a dictionary...
switch (location)
{
case LookupLocation.RequiredChildren:
if (this.requiredChildren.ContainsKey(key))
return this.requiredChildren[key] as T;
break;
case LookupLocation.OptionalChildren:
if (this.optionalChildren.ContainsKey(key))
return this.optionalChildren[key] as T;
break;
}
// Nothing
return null;
}
/// <summary>
/// Returns whether this rule has child rule specified by the key.
/// </summary>
/// <param name="key">Child key.</param>
/// <returns></returns>
public bool HasChild(string key)
{
return (this.requiredChildren.ContainsKey(key) || this.optionalChildren.ContainsKey(key));
}
/// <summary>
/// Looks up the evaluated parental child rule by its name in the default lookup dictionary specified by the <see cref="DefaultChildLookupLocation"/> property.
/// </summary>
/// <param name="key">Child key.</param>
/// <returns>Evaluated parental child rule.</returns>
public EvaluatedParentalRule LookupParentalChild(string key)
{
return LookupParentalChild(key, this.defaultChildLookupLocation);
}
/// <summary>
/// Looks up the evaluated parental child rule by its name in the specified lookup dictionary.
/// </summary>
/// <param name="key">Child key.</param>
/// <param name="location">Lookup dictionary.</param>
/// <returns>Evaluated parental child rule.</returns>
public EvaluatedParentalRule LookupParentalChild(string key, LookupLocation location)
{
return this.LookupChildAs<EvaluatedParentalRule>(key, location);
}
/// <summary>
/// Looks up evaluated child rules by their common name in the default lookup dictionary specified by the <see cref="DefaultChildLookupLocation"/> property.
/// </summary>
/// <param name="commonKey">Common key.</param>
/// <returns>Evaluated child rules.</returns>
public IEnumerable<EvaluatedRule> LookupChildren(string commonKey)
{
return this.LookupChildren(commonKey, this.defaultChildLookupLocation, CultureInfo.CurrentCulture);
}
/// <summary>
/// Looks up evaluated child rules by their common name in the specified lookup dictionary.
/// </summary>
/// <param name="commonKey">Common key.</param>
/// <param name="location">Lookup dictionary.</param>
/// <returns>Evaluated child rules.</returns>
public IEnumerable<EvaluatedRule> LookupChildren(string commonKey, LookupLocation location)
{
return this.LookupChildren(commonKey, location, CultureInfo.CurrentCulture);
}
/// <summary>
/// Looks up evaluated child rules by their common name using the provided culture info in the default lookup dictionary specified by the <see cref="DefaultChildLookupLocation"/> property.
/// </summary>
/// <param name="commonKey">Common key.</param>
/// <param name="culture">Culture info.</param>
/// <returns>Evaluated child rules.</returns>
public IEnumerable<EvaluatedRule> LookupChildren(string commonKey, CultureInfo culture)
{
return this.LookupChildren(commonKey, this.defaultChildLookupLocation, culture);
}
/// <summary>
/// Looks up evaluated child rules by their common name using the provided culture info in the default lookup dictionary specified by the <see cref="DefaultChildLookupLocation"/> property.
/// </summary>
/// <param name="commonKey">Common key.</param>
/// <param name="location">Lookup dictionary.</param>
/// <param name="culture">Culture info.</param>
/// <returns>Evaluated child rules.</returns>
public IEnumerable<EvaluatedRule> LookupChildren(string commonKey, LookupLocation location, CultureInfo culture)
{
// Go through all children in the desired location and return each one under the common key...
foreach (KeyValuePair<string, EvaluatedRule> rulePair in location == LookupLocation.RequiredChildren ? this.requiredChildren : this.optionalChildren)
if (rulePair.Key.StartsWith(commonKey, true, culture))
yield return rulePair.Value;
}
/// <summary>
/// Returns an evaluated rule linked to this rule before the evaluation.
/// </summary>
/// <param name="rule">Linked rule.</param>
/// <returns>Evaluated rule.</returns>
public EvaluatedRule GetEvaluatedLinkedRule(Rule rule)
{
// Check for null...
if (rule == null) throw new ArgumentNullException("rule");
// Rule cookie
string ruleName = rule.ruleCookie.ToString();
// Did we tracked this rule?
if (!this.LinkedEvaluatedRules.ContainsKey(ruleName))
throw new KeyNotFoundException(Resources.ExceptionMsg_LinkNotFound);
// Return evaluated tracked rule
return this.LinkedEvaluatedRules[ruleName];
}
/// <summary>
/// Returns an evaluated rule linked to this rule before the evaluation. The rule is casted to an instance of the <see cref="EvaluatedParentalRule"/>.
/// </summary>
/// <param name="rule">Linked rule.</param>
/// <returns>Evaluated parental rule.</returns>
public EvaluatedParentalRule GetEvaluatedParentalLinkedRule(Rule rule)
{
return this.GetEvaluatedLinkedRule(rule) as EvaluatedParentalRule;
}
/// <summary>
/// Returns an evaluated rule linked to this rule before the evaluation. The rule is casted to an instance of the <paramref name="T"/> type.
/// </summary>
/// <param name="rule">Linked rule.</param>
/// <typeparam name="T">Type to cast the rule to.</typeparam>
/// <returns>Casted evaluated rule.</returns>
public T GetEvaluatedLinkedRuleAs<T>(Rule rule) where T : EvaluatedRule
{
return this.GetEvaluatedLinkedRule(rule) as T;
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I'm a student of the Low-voltage Electrical Engineering specialized on Computing from the Czech republic.
I'm a C# kind of guy, fan of .NET.
I've formed a programming group called 'Comnicate!'. Currently the only member of the group is myself.