示例#1
0
        /// <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);
        }
示例#2
0
        /// <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);
        }