| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038 |
- #if NET_2_0
- /*
- Used to determine Browser Capabilities by the Browsers UserAgent String and related
- Browser supplied Headers.
- Copyright (C) 2002-Present Owen Brady (Ocean at owenbrady dot net)
- and Dean Brettle (dean at brettle dot com)
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is furnished
- to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- namespace System.Web.Configuration.nBrowser
- {
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Text.RegularExpressions;
-
- internal class Node
- {
- #region Public Properties
- /// <summary>
- ///
- /// </summary>
- public NodeType NameType
- {
- get
- {
- return pName;
- }
- set
- {
- pName = value;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public string Id
- {
- get
- {
- return pId;
- }
- set
- {
- pId = value;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public string ParentId
- {
- get
- {
- return pParentID;
- }
- set
- {
- pParentID = value;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public string RefId
- {
- get
- {
- return pRefID;
- }
- set
- {
- pRefID = value;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public string MarkupTextWriterType
- {
- get
- {
- return pMarkupTextWriterType;
- }
- set
- {
- pMarkupTextWriterType = value;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public string FileName
- {
- get
- {
- return pFileName;
- }
- set
- {
- pFileName = value;
- }
- }
- #endregion
- private NodeType pName = NodeType.None;
- private string pId = string.Empty;
- private string pParentID = string.Empty;
- private string pRefID = string.Empty;
- private string pMarkupTextWriterType = string.Empty;
- private string pFileName = string.Empty;
- private System.Xml.XmlNode xmlNode;
- private Identification[] Identification;
- private Identification[] Capture;
- private System.Collections.Specialized.NameValueCollection Capabilities;
- private System.Collections.Specialized.NameValueCollection Adapter;
- private Type[] AdapterControlTypes, AdapterTypes;
- private System.Collections.Generic.List<string> ChildrenKeys;
- private System.Collections.Generic.List<string> DefaultChildrenKeys;
- private System.Collections.Generic.SortedList<string, nBrowser.Node> Children;
- private System.Collections.Generic.SortedList<string, nBrowser.Node> DefaultChildren;
- private System.Collections.Specialized.NameValueCollection sampleHeaders;
- /// <summary>
- ///
- /// </summary>
- /// <param name="xmlNode"></param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059")]
- public Node(System.Xml.XmlNode xmlNode)
- {
- this.xmlNode = xmlNode;
- this.ResetChildern();
- this.Reset();
- }
- /// <summary>
- ///
- /// </summary>
- internal Node()
- {
- this.ResetChildern();
- Identification = new System.Web.Configuration.nBrowser.Identification[1];
- Identification[0] = new System.Web.Configuration.nBrowser.Identification(true, "header", "User-Agent", ".");
- this.Id = "[Base Node]";
- this.NameType = NodeType.Browser;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="node"></param>
- private void ProcessIdentification(System.Xml.XmlNode node)
- {
- //I know not all of these will be used but enough will
- Identification = new System.Web.Configuration.nBrowser.Identification[node.ChildNodes.Count];
- int i = -1;
- for (int a = 0;a <= node.ChildNodes.Count - 1;a++)
- {
- switch (node.ChildNodes[a].NodeType)
- {
- case System.Xml.XmlNodeType.Text:
- continue;
- case System.Xml.XmlNodeType.Comment:
- continue;
- }
- string patterngroup = string.Empty;
- string patternname = string.Empty;
- if (string.Compare(node.ChildNodes[a].Name, "userAgent", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- patterngroup = "header";
- patternname = "User-Agent";
- }
- else if (string.Compare(node.ChildNodes[a].Name, "header", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- patterngroup = node.ChildNodes[a].Name;
- patternname = node.ChildNodes[a].Attributes["name"].Value;
- }
- else if (string.Compare(node.ChildNodes[a].Name, "capability", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- patterngroup = node.ChildNodes[a].Name;
- patternname = node.ChildNodes[a].Attributes["name"].Value;
- }
- else
- {
- throw new nBrowser.Exception("Invalid Node found in Identification");
- }
- if (node.ChildNodes[a].Attributes["match"] != null)
- {
- i++;
- Identification[i] = new System.Web.Configuration.nBrowser.Identification(true, patterngroup, patternname, node.ChildNodes[a].Attributes["match"].Value);
- }
- else if (node.ChildNodes[a].Attributes["nonMatch"] != null)
- {
- i++;
- Identification[i] = new System.Web.Configuration.nBrowser.Identification(false, patterngroup, patternname, node.ChildNodes[a].Attributes["nonMatch"].Value);
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="node"></param>
- private void ProcessCapture(System.Xml.XmlNode node)
- {
- //I know not all of these will be used but enough will
- Capture = new System.Web.Configuration.nBrowser.Identification[node.ChildNodes.Count];
- int i = -1;
- for (int a = 0;a <= node.ChildNodes.Count - 1;a++)
- {
- switch (node.ChildNodes[a].NodeType)
- {
- case System.Xml.XmlNodeType.Text:
- continue;
- case System.Xml.XmlNodeType.Comment:
- continue;
- }
- string pattern = string.Empty;
- string patterngroup = string.Empty;
- string patternname = string.Empty;
- if (node.ChildNodes[a].Name == "userAgent")
- {
- patterngroup = "header";
- patternname = "User-Agent";
- }
- else
- {
- patterngroup = node.ChildNodes[a].Name;
- patternname = node.ChildNodes[a].Attributes["name"].Value;
- }
- pattern = node.ChildNodes[a].Attributes["match"].Value;
- i++;
- Capture[i] = new System.Web.Configuration.nBrowser.Identification(true, patterngroup, patternname, pattern);
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="node"></param>
- private void ProcessCapabilities(System.Xml.XmlNode node)
- {
- Capabilities = new System.Collections.Specialized.NameValueCollection(node.ChildNodes.Count, StringComparer.OrdinalIgnoreCase);
- for (int a = 0;a <= node.ChildNodes.Count - 1;a++)
- {
- if (node.ChildNodes[a].NodeType == System.Xml.XmlNodeType.Comment)
- {
- continue;
- }
- string name = string.Empty;
- string value = string.Empty;
- for (int b = 0;b <= node.ChildNodes[a].Attributes.Count - 1;b++)
- {
- switch (node.ChildNodes[a].Attributes[b].Name)
- {
- case "name":
- name = node.ChildNodes[a].Attributes[b].Value;
- break;
- case "value":
- value = node.ChildNodes[a].Attributes[b].Value;
- break;
- }
- }
- if (name.Length > 0)
- {
- Capabilities[name] = value;
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="node"></param>
- private void ProcessControlAdapters(System.Xml.XmlNode node)
- {
- Adapter = new System.Collections.Specialized.NameValueCollection();
- for (int b = 0;b <= node.Attributes.Count - 1;b++)
- {
- switch (node.Attributes[b].Name)
- {
- case "markupTextWriterType":
- MarkupTextWriterType = node.Attributes[b].Value;
- break;
- }
- }
- for (int a = 0;a <= node.ChildNodes.Count - 1;a++)
- {
- if (node.ChildNodes[a].NodeType == System.Xml.XmlNodeType.Comment)
- {
- continue;
- }
- else if (node.ChildNodes[a].NodeType == System.Xml.XmlNodeType.Text)
- {
- continue;
- }
- System.Xml.XmlNode x = node.ChildNodes[a];
- string controlType = string.Empty;
- string adapterType = string.Empty;
- for (int i = 0;i <= x.Attributes.Count - 1;i++)
- {
- if (string.Compare(x.Attributes[i].Name, "controlType", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- controlType = x.Attributes[i].Value;
- }
- else if (string.Compare(x.Attributes[i].Name, "adapterType", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- adapterType = x.Attributes[i].Value;
- }
- }
- if (controlType.Length > 0 && adapterType.Length > 0)
- {
- Adapter[controlType] = adapterType;
- }
- }
- AdapterControlTypes = null;
- AdapterTypes = null;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="node"></param>
- private void ProcessSampleHeaders(System.Xml.XmlNode node)
- {
- sampleHeaders = new System.Collections.Specialized.NameValueCollection(node.ChildNodes.Count);
- for (int a = 0;a <= node.ChildNodes.Count - 1;a++)
- {
- if (node.ChildNodes[a].NodeType == System.Xml.XmlNodeType.Comment)
- {
- continue;
- }
- string name = string.Empty;
- string value = string.Empty;
- for (int b = 0;b <= node.ChildNodes[a].Attributes.Count - 1;b++)
- {
- switch (node.ChildNodes[a].Attributes[b].Name)
- {
- case "name":
- name = node.ChildNodes[a].Attributes[b].Value;
- break;
- case "value":
- value = node.ChildNodes[a].Attributes[b].Value;
- break;
- }
- }
- if (name.Length > 0)
- {
- sampleHeaders[name] = value;
- }
- }
- }
- internal void ResetChildern()
- {
- Children = new System.Collections.Generic.SortedList<string, nBrowser.Node>();
- DefaultChildren = new System.Collections.Generic.SortedList<string, nBrowser.Node>();
- ChildrenKeys = new System.Collections.Generic.List<string>();
- DefaultChildrenKeys = new System.Collections.Generic.List<string>();
- }
- /// <summary>
- ///
- /// </summary>
- public bool HasChildren
- {
- get
- {
- if (Children.Count > -1)
- {
- return true;
- }
- return false;
- }
- }
- /// <summary>
- ///
- /// </summary>
- public void Reset()
- {
- //Making sure we start off on a good footing.
- Capture = null;
- Capabilities = null;
- Adapter = null;
- AdapterControlTypes = null;
- AdapterTypes = null;
- if (string.Compare(this.xmlNode.Name, "browser", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- this.NameType = NodeType.Browser;
- }
- else if (string.Compare(this.xmlNode.Name, "defaultBrowser", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- this.NameType = NodeType.DefaultBrowser;
- }
- else if (string.Compare(this.xmlNode.Name, "gateway", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- this.NameType = NodeType.Gateway;
- }
- //-------------------------------------------------------------------------
- //Looping though the Attributes is easier since and more efficient
- //then doing finds for specific attribute names. This also handles the
- //cases where there are no attributes really well. Also it doesn't care
- //about the order in witch the attributes are found either
- //-------------------------------------------------------------------------
- for (int a = 0;a <= xmlNode.Attributes.Count - 1;a++)
- {
- //Reason I am not using a switch here because I do not have the ability
- //to make sure the items are in the same upper/lower case as I am expecting
- //so I default to ignore case and compare.
- if (string.Compare(xmlNode.Attributes[a].Name, "id", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- Id = xmlNode.Attributes[a].Value.ToLower(System.Globalization.CultureInfo.CurrentCulture);
- }
- else if (string.Compare(xmlNode.Attributes[a].Name, "parentID", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- ParentId = xmlNode.Attributes[a].Value.ToLower(System.Globalization.CultureInfo.CurrentCulture);
- }
- else if (string.Compare(xmlNode.Attributes[a].Name, "refID", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- RefId = xmlNode.Attributes[a].Value.ToLower(System.Globalization.CultureInfo.CurrentCulture);
- }
- }
- for (int a = 0;a <= xmlNode.ChildNodes.Count - 1;a++)
- {
- //Reason I am not using a switch here because I do not have the ability
- //to make sure the items are in the same upper/lower case as I am expecting
- //so I default to ignore case and compare.
- if (string.Compare(xmlNode.ChildNodes[a].Name, "identification", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- ProcessIdentification(xmlNode.ChildNodes[a]);
- }
- else if (string.Compare(xmlNode.ChildNodes[a].Name, "capture", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- ProcessCapture(xmlNode.ChildNodes[a]);
- }
- else if (string.Compare(xmlNode.ChildNodes[a].Name, "capabilities", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- ProcessCapabilities(xmlNode.ChildNodes[a]);
- }
- else if (string.Compare(xmlNode.ChildNodes[a].Name, "controlAdapters", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- ProcessControlAdapters(xmlNode.ChildNodes[a]);
- }
- else if (string.Compare(xmlNode.ChildNodes[a].Name, "sampleHeaders", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- ProcessSampleHeaders(xmlNode.ChildNodes[a]);
- }
-
- if (Id == "default" && (Identification == null || Identification.Length == 0))
- {
- Identification = new Identification[1];
- Identification[0] = new System.Web.Configuration.nBrowser.Identification(true, "header", "User-Agent", ".");
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="child"></param>
- public void AddChild(Node child)
- {
- if (child == null)
- {
- return;
- }
- if (child.NameType == nBrowser.NodeType.Browser || child.NameType == nBrowser.NodeType.Gateway)
- {
- Children.Add(child.Id, child);
- ChildrenKeys.Add(child.Id);
- }
- else if (child.NameType == NodeType.DefaultBrowser)
- {
- DefaultChildren.Add(child.Id, child);
- DefaultChildrenKeys.Add(child.Id);
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="child"></param>
- public void RemoveChild(Node child)
- {
- if (child == null)
- {
- return;
- }
- if (child.NameType == nBrowser.NodeType.Browser || child.NameType == nBrowser.NodeType.Gateway)
- {
- Children.Remove(child.Id);
- ChildrenKeys.Remove(child.Id);
- }
- else if (child.NameType == NodeType.DefaultBrowser)
- {
- DefaultChildren.Remove(child.Id);
- DefaultChildrenKeys.Remove(child.Id);
- }
- }
-
- private Type FindType(string typeName)
- {
- foreach (System.Reflection.Assembly a in System.AppDomain.CurrentDomain.GetAssemblies())
- {
- string fullTypeName = typeName + "," + a.FullName;
- Type t = System.Type.GetType(fullTypeName); // case-sensitive
- if (t != null)
- return t;
- t = System.Type.GetType(fullTypeName, false, true); // case-insensitive
- if (t != null)
- return t;
- }
- throw new TypeLoadException(typeName);
- }
-
- /// <summary>
- /// Matches the header collection against this subtree and uses the matchList
- /// and any new matches to augment the result. This method calls ProcessSubtree()
- /// but then removes the matches that it adds to the matchList.
- /// </summary>
- /// <param name="header">the header collection to evaluate (invariant)</param>
- /// <param name="result">the result of the match (might be changed if a match is found)</param>
- /// <param name="matchList">the matches to use to do substitutions (invariant)</param>
- /// <returns>true iff this node or one of it's descendants matches</returns>
- internal bool Process(System.Collections.Specialized.NameValueCollection header, nBrowser.Result result,
- System.Collections.Generic.List<Match> matchList)
- {
- // The real work is done in ProcessSubtree. This method just ensures that matchList is restored
- // to its original state before returning.
- int origMatchListCount = matchList.Count;
- bool matched = ProcessSubtree(header, result, matchList);
- if (matchList.Count > origMatchListCount)
- matchList.RemoveRange(origMatchListCount, matchList.Count-origMatchListCount);
- return matched;
- }
-
- /// <summary>
- /// Matches the header collection against this subtree, adds any new matches for this node to
- /// matchList, and uses the matchList to augment the result.
- /// </summary>
- /// <param name="header">the header collection to evaluate (invariant)</param>
- /// <param name="result">the result of the match (might be changed if a match is found)</param>
- /// <param name="matchList">the matches to use to do substitutions,
- /// possibly including new matches for this node.</param>
- /// <returns>true iff this node or one of it's descendants matches</returns>
- private bool ProcessSubtree(System.Collections.Specialized.NameValueCollection header, nBrowser.Result result, System.Collections.Generic.List<Match> matchList)
- {
- //----------------------------------------------------------------------
- //This is just coded over from MS version since if you pass in an empty
- //string for the key it returns the UserAgent header as a response.
- //----------------------------------------------------------------------
- result.AddCapabilities("", header["User-Agent"]);
- if (RefId.Length == 0 && this.NameType != NodeType.DefaultBrowser)
- {
- //----------------------------------------------------------------------
- //BrowserIdentification adds all the Identifiction matches to the match
- //list if this node matches.
- //----------------------------------------------------------------------
- if (!BrowserIdentification(header, result, matchList))
- return false;
- }
- result.AddMatchingBrowserId (this.Id);
- #region Browser Identification Successfull
- //----------------------------------------------------------------------
- //By reaching this point, it either means there were no Identification
- //items to be processed or that all the Identification items have been
- //passed. So just for debuging I want to output this Groups unique ID.
- //----------------------------------------------------------------------
- result.AddTrack("[" + this.NameType + "]\t" + this.Id);
- //----------------------------------------------------------------------
- //Just adding all the Adapters to the current list.
- //----------------------------------------------------------------------
- if (Adapter != null)
- {
- LookupAdapterTypes();
- for (int i = 0;i <= Adapter.Count - 1;i++)
- {
- result.AddAdapter(AdapterControlTypes [i], AdapterTypes [i]);
- }
- }
- //----------------------------------------------------------------------
- //Set the MarkupTextWriter in the result if set in this node.
- //----------------------------------------------------------------------
- if (MarkupTextWriterType != null && MarkupTextWriterType.Length > 0)
- {
- // Look for the type using a case-sensitive search
- result.MarkupTextWriter = Type.GetType(MarkupTextWriterType);
- // If we don't find it, try again using a case-insensitive search and throw
- // and exception if we can't find it.
- if (result.MarkupTextWriter == null)
- result.MarkupTextWriter = Type.GetType(MarkupTextWriterType, true, true);
- }
- #endregion
- #region Capture
- if (Capture != null)
- {
- //----------------------------------------------------------------------
- //Adds all the sucessfull Capture matches to the matchList
- //----------------------------------------------------------------------
- for (int i = 0;i <= Capture.Length - 1;i++)
- {
- //shouldn't happen often, the null should
- //signal the end of the list, I keep procssing
- //the rest just in case
- if (Capture[i] == null)
- {
- continue;
- }
- Match m = null;
- if (Capture[i].Group == "header")
- {
- m = Capture[i].GetMatch(header[Capture[i].Name]);
- }
- else if (Capture[i].Group == "capability")
- {
- m = Capture[i].GetMatch(result[Capture[i].Name]);
- }
- if (Capture[i].IsMatchSuccessful(m) && m.Groups.Count > 0)
- {
- matchList.Add(m);
- }
- }
- }
- #endregion
- #region Capabilities
- if (Capabilities != null)
- {
- //----------------------------------------------------------------------
- //This section is what the whole exercise is about. Determining
- //the Browser Capabilities. We know already that the current
- //browser matches the criteria, now its a mater of updating
- //the results with the new Capabilties listed.
- //----------------------------------------------------------------------
- for (int i = 0;i <= Capabilities.Count - 1;i++)
- {
- //----------------------------------------------------------------------
- //We need to further process these Capabilities to
- //insert the proper information.
- //----------------------------------------------------------------------
- string v = Capabilities[i];
- //----------------------------------------------------------------------
- //Loop though the list of Identifiction/Capture Matches
- //in reverse order. Meaning the newest Items in the list
- //get checked first, then working to the oldest. Often times
- //Minor /Major revisition numbers will be listed multple times
- //and only the newest one (most recent matches) are the ones
- //we want to insert.
- //----------------------------------------------------------------------
- for (int a = matchList.Count - 1; a >= 0 && v != null && v.Length > 0 && v.IndexOf('$') > -1; a--)
- {
- // Don't do substitution if the match has no groups or was a nonMatch
- if (matchList[a].Groups.Count == 0 || !matchList[a].Success)
- continue;
- v = matchList[a].Result(v);
- }
- //----------------------------------------------------------------------
- //Checks to make sure we extract the result we where looking for.
- //----------------------------------------------------------------------
- if (v.IndexOf('$') > -1 || v.IndexOf('%') > -1)
- {
- //----------------------------------------------------------------------
- //Microsoft has a nasty habbit of using capability items in regular expressions
- //so I have to figure a nice way to working around it
- // <capability name="msdomversion" value="${majorversion}${minorversion}" />
- //----------------------------------------------------------------------
- //double checks the values against the current Capabilities. to
- //find any last minute matches. that are not defined by regluar
- //expressions
- v = result.Replace(v);
- }
- result.AddCapabilities(Capabilities.Keys[i], v);
- }
- }
- #endregion
- //----------------------------------------------------------------------
- //Run the Default Children after the Parent Node is finished with
- //what it is doing
- //----------------------------------------------------------------------
- for (int i = 0;i <= DefaultChildren.Count - 1;i++)
- {
- string key = DefaultChildrenKeys[i];
- Node node = DefaultChildren[key];
- if (node.NameType == NodeType.DefaultBrowser)
- {
- node.Process(header, result, matchList);
- }
- }
- //----------------------------------------------------------------------
- //processing all the children Browsers of this Parent if there are any.
- //----------------------------------------------------------------------
- //In nBrowser files, the Gateways should of been sorted so they are all
- //at the top so that they can be ran first.
- //----------------------------------------------------------------------
- //According to the msdn2 documentation Gateways are suppost to be
- //all processed first. before the browser objects.
- for (int i = 0;i <= Children.Count - 1;i++)
- {
- string key = ChildrenKeys[i];
- Node node = Children[key];
- if (node.NameType == NodeType.Gateway)
- {
- node.Process(header, result, matchList);
- }
- }
- for (int i = 0;i <= Children.Count - 1;i++)
- {
- string key = ChildrenKeys[i];
- Node node = Children[key];
- if (node.NameType == NodeType.Browser
- && node.Process(header, result, matchList))
- break;
- }
- return true;
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="header"></param>
- /// <param name="result"></param>
- /// <param name="matchList"></param>
- /// <returns>true iff this node is a match</returns>
- private bool BrowserIdentification(System.Collections.Specialized.NameValueCollection header, System.Web.Configuration.CapabilitiesResult result, System.Collections.Generic.List<Match> matchList)
- {
- if (Id.Length > 0 && RefId.Length > 0)
- {
- throw new nBrowser.Exception("Id and refID Attributes givin when there should only be one set not both");
- }
- if (Identification == null || Identification.Length == 0)
- {
- throw new nBrowser.Exception(String.Format("Missing Identification Section where one is required (Id={0}, RefID={1})", Id, RefId));
- }
- if (header == null)
- {
- throw new nBrowser.Exception("Null Value where NameValueCollection expected ");
- }
- if (result == null)
- {
- throw new nBrowser.Exception("Null Value where Result expected ");
- }
- #if trace
- System.Diagnostics.Trace.WriteLine(string.Format("{0}[{1}]", ("[" + this.Id + "]").PadRight(45), this.ParentId));
- #endif
-
- for (int i = 0;i <= Identification.Length - 1;i++)
- {
- //shouldn't happen often, the null should
- //signal the end of the list, I keep procssing
- //the rest just in case
- if (Identification[i] == null)
- {
- continue;
- }
- string v = string.Empty;
- if (string.Compare(Identification[i].Group, "header", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- v = header[Identification[i].Name];
- }
- else if (string.Compare(Identification[i].Group, "capability", true, System.Globalization.CultureInfo.CurrentCulture) == 0)
- {
- v = result[Identification[i].Name];
- }
- //Not all headers will be sent by all browsers.
- //so often a header search will return Null.
- if (v == null)
- {
- v = string.Empty;
- }
- Match m = Identification[i].GetMatch(v);
- //----------------------------------------------------------------------
- //we exit this method return the orginal Result back to the calling method.
- //----------------------------------------------------------------------
- if (Identification[i].IsMatchSuccessful(m) == false)
- {
- #if trace
- System.Diagnostics.Trace.WriteLine(string.Format("{0}{1}", "Failed:".PadRight(45), Identification[i].Pattern));
- #endif
- return false;
- }
- else
- {
- #if trace
- System.Diagnostics.Trace.WriteLine(string.Format("{0}{1}", "Passed:".PadRight(45), Identification[i].Pattern));
- #endif
- if (m.Groups.Count > 0)
- {
- matchList.Add(m);
- }
- }
- }
- #if trace
- System.Diagnostics.Trace.WriteLine("");
- #endif
- return true;
- }
-
- private bool HaveAdapterTypes = false;
- private object LookupAdapterTypesLock = new object();
- private void LookupAdapterTypes()
- {
- if (Adapter == null || HaveAdapterTypes) return;
- lock (LookupAdapterTypesLock)
- {
- if (HaveAdapterTypes) return;
- /* Lookup the types and store them for future use */
- if (AdapterControlTypes == null)
- AdapterControlTypes = new Type [Adapter.Count];
- if (AdapterTypes == null)
- AdapterTypes = new Type [Adapter.Count];
- for (int i = 0;i <= Adapter.Count - 1;i++) {
- if (AdapterControlTypes [i] == null)
- AdapterControlTypes [i] = FindType (Adapter.GetKey (i));
- if (AdapterTypes [i] == null)
- AdapterTypes [i] = FindType (Adapter [i]);
- }
- HaveAdapterTypes = true;
- }
- }
-
- /// <summary>
- ///
- /// </summary>
- public System.Collections.Specialized.NameValueCollection SampleHeader
- {
- get
- {
- return sampleHeaders;
- }
- }
- /// <summary>
- /// Used to Display a Tree Like View of how the Nodes are organized.
- /// </summary>
- /// <param name="writer"></param>
- /// <param name="Position"></param>
- public void Tree(System.Xml.XmlTextWriter xmlwriter, int position)
- {
- if (position == 0)
- {
- xmlwriter.WriteStartDocument();
- xmlwriter.WriteStartElement(this.NameType.ToString());
- xmlwriter.WriteRaw(System.Environment.NewLine);
- }
- string f = this.FileName;
- xmlwriter.WriteStartElement(this.NameType.ToString());
- xmlwriter.WriteAttributeString("FileName", f);
- xmlwriter.WriteAttributeString("ID", this.Id);
- xmlwriter.WriteRaw(System.Environment.NewLine);
- if (position != int.MaxValue)
- {
- position++;
- }
- for (int i = 0;i <= DefaultChildren.Count - 1;i++)
- {
- string key = (string)DefaultChildrenKeys[i];
- Node node = DefaultChildren[key];
- if (node.NameType == nBrowser.NodeType.DefaultBrowser)
- {
- node.Tree(xmlwriter, position);
- }
- }
- for (int i = 0;i <= Children.Count - 1;i++)
- {
- string key = (string)ChildrenKeys[i];
- Node node = Children[key];
- if (node.NameType == nBrowser.NodeType.Gateway)
- {
- node.Tree(xmlwriter, position);
- }
- }
- for (int i = 0;i <= Children.Count - 1;i++)
- {
- string key = (string)ChildrenKeys[i];
- Node node = Children[key];
- if (node.NameType == nBrowser.NodeType.Browser)
- {
- node.Tree(xmlwriter, position);
- }
- }
- if (position != int.MinValue)
- {
- position--;
- }
- xmlwriter.WriteEndElement();
- xmlwriter.WriteRaw(System.Environment.NewLine);
- if (position == 0)
- {
- xmlwriter.WriteEndDocument();
- xmlwriter.Flush();
- }
- }
- public System.Collections.ObjectModel.Collection<string> HeaderNames(System.Collections.ObjectModel.Collection<string> list)
- {
- if (Identification != null)
- {
- for (int i = 0;i <= Identification.Length - 1;i++)
- {
- if (Identification[i] == null)
- {
- continue;
- }
- if (Identification[i].Group == "header")
- {
- if (list.Contains(Identification[i].Name) == false)
- {
- list.Add(Identification[i].Name);
- }
- }
- }
- }
- if (Capture != null)
- {
- for (int i = 0;i <= Capture.Length - 1;i++)
- {
- if (Capture[i] == null)
- {
- continue;
- }
- if (Capture[i].Group == "header")
- {
- if (list.Contains(Capture[i].Name) == false)
- {
- list.Add(Capture[i].Name);
- }
- }
- }
- }
- for (int i = 0;i <= DefaultChildren.Count - 1;i++)
- {
- string key = (string)DefaultChildrenKeys[i];
- Node node = DefaultChildren[key];
- if (node.NameType == nBrowser.NodeType.DefaultBrowser)
- {
- list = node.HeaderNames(list);
- }
- }
- for (int i = 0;i <= Children.Count - 1;i++)
- {
- string key = (string)ChildrenKeys[i];
- Node node = Children[key];
- if (node.NameType == nBrowser.NodeType.Gateway)
- {
- list = node.HeaderNames(list);
- }
- }
- for (int i = 0;i <= Children.Count - 1;i++)
- {
- string key = (string)ChildrenKeys[i];
- Node node = Children[key];
- if (node.NameType == nBrowser.NodeType.Browser)
- {
- list = node.HeaderNames(list);
- }
- }
- return list;
- }
-
- /// <summary>
- /// Merge capabilities, captures, markupTextWriters, and adapters from another Node into this Node.
- /// </summary>
- /// <param name="n">node to merge with this node</param>
- public void MergeFrom(Node n)
- {
- if (n.Capabilities != null)
- {
- if (Capabilities == null)
- Capabilities = new System.Collections.Specialized.NameValueCollection(n.Capabilities.Count, StringComparer.OrdinalIgnoreCase);
- foreach (string capName in n.Capabilities)
- Capabilities[capName] = n.Capabilities[capName];
- }
-
- int newLength = 0;
- if (Capture != null)
- newLength += Capture.Length;
- if (n.Capture != null)
- newLength += n.Capture.Length;
- Identification[] newCapture = new Identification[newLength];
- if (Capture != null)
- Array.Copy(Capture, 0, newCapture, 0, Capture.Length);
- if (n.Capture != null)
- Array.Copy(n.Capture, 0, newCapture, (Capture != null ? Capture.Length : 0), n.Capture.Length);
- Capture = newCapture;
-
- if (n.MarkupTextWriterType != null && n.MarkupTextWriterType.Length > 0)
- MarkupTextWriterType = n.MarkupTextWriterType;
-
- if (n.Adapter != null)
- {
- if (Adapter == null)
- Adapter = new System.Collections.Specialized.NameValueCollection();
- foreach (string controlType in n.Adapter)
- Adapter[controlType] = n.Adapter[controlType];
- }
- }
- }
- }
- #endif
|