Beispiel #1
0
        /// <summary> This methods processes the Rule nodes that may exist in the XML.
        /// <P>
        /// It executes as follows (this may not look so straightforward in the code...):
        /// <OL>
        /// <LI>Executes Factories executeRule()</LI>
        /// <LI>takes the result and puts it into a RuleResult object</LI>
        /// <LI>listeners.dispatches an error if it could not find the factory
        /// (See docs in code)</LI>
        /// <LI>Catches any exceptions from the executeRule() and makes it a
        /// RuleResult so it can be handled gracefully</LI>
        /// <LI>Adds the RuleResult to the CallStack</LI>
        /// <LI>listeners.dispatched the RuleResult to any listeners</LI>
        /// <LI>Adds the RuleResult to the RuleContext</LI>
        /// </OL>
        /// </P>
        /// </summary>
        /// <param name="id">The ID of the Rule
        /// </param>
        /// <param name="step">The current Step
        /// </param>
        /// <param name="aMap">The Parameters map
        /// </param>
        private void DoRule(object id, object step, Hashtable aMap)
        {
            int nextStackLoc = ruleContext.CallStack.Count;

            IBRERuleResult ruleResult = null;

            try
            {
                IBRERuleFactory factory = ruleContext.GetFactory(id);

                /*
                 * I have to check for null because if the RuleContext
                 * was passed in, an external reference exists and can be
                 * modified at any time
                 */

                if (factory != null)
                {
                    //setup metadata
                    IBRERuleMetaData metaData = new BRERuleMetaDataImpl(id, factory, aMap, nextStackLoc, step);

                    object result = factory.ExecuteRule(ruleContext, aMap, step);

                    ruleResult = new BRERuleResultImpl(metaData, result);
                }
                else
                {
                    /*
                     * A WARN version of this error can occur when the
                     * Factories are loaded.  But if the developer passed in
                     * a RuleContext, they can place the Factory into the
                     * RuleContext still.  If we get to this point it is now a full
                     * blown error because if it is not in the RuleContext at this point and
                     * it to late and can cause issues
                     */

                    if (Logger.IsFlowEngineError)
                    {
                        Logger.FlowEngineSource.TraceData(TraceEventType.Error, 0, new BREException("Factory Id " + id + " defined, but not found in RuleContext"));
                    }
                }
            }
            // This can occur internally in the RuleContext
            catch (System.InvalidCastException cce)
            {
                if (Logger.IsFlowEngineCritical)
                {
                    Logger.FlowEngineSource.TraceData(TraceEventType.Critical, 0, new BREException("Object in RuleContext not of correct type. " + cce.ToString()));
                }
            }
            // Catch unknown exceptions in the factory itself
            catch (System.Exception e)
            {
                if (Logger.IsFlowEngineError)
                {
                    Logger.FlowEngineSource.TraceData(TraceEventType.Error, 0, new BREException("Error when processing RuleFactory id: " + id, e));
                }

                /*
                 * Set the RuleResult to an exception so I can test for it in the If
                 * Hey, technically it IS what it returned ;)
                 * The factory can return null here, but that could have caused the
                 * exception anyway.....
                 */

                IBRERuleMetaData metaData = new BRERuleMetaDataImpl(id, ruleContext.GetFactory(id), aMap, nextStackLoc, step);
                ruleResult = new BRERuleResultImpl(metaData, e);
            }

            ruleContext.CallStack.Push(ruleResult);

            // call listeners
            DispatchRuleResult(ruleResult);

            ruleContext.SetResult(id, ruleResult);
        }