/// <summary> /// Process the math operation by parsing the text and computing the /// result. /// </summary> /// <param name="data">FlowData to add the result to</param> protected override void ProcessInternal(IFlowData data) { MathData elementData = (MathData)data.GetOrAdd( ElementDataKeyTyped, (f) => base.CreateElementData(f)); string operation = ((string)data.GetEvidence()[EvidenceKeys[0]]); if (operation != null) { // Parse the text representation of the mathematical operation. elementData.Operation = operation .Replace("plus", "+") .Replace("minus", "-") .Replace("divide", "/") .Replace("times", "*"); // Compute the value of the operation. elementData.Result = Convert.ToDouble( new DataTable().Compute(elementData.Operation, "")); } else { // Nothing provided, so just set zeros. elementData.Operation = "0"; elementData.Result = 0; } }
protected override void ProcessInternal(IFlowData data) { // Create a new IStarSignData, and cast to StarSignData so the 'setter' is available. StarSignData starSignData = (StarSignData)data.GetOrAdd(ElementDataKey, CreateElementData); if (data.TryGetEvidence("date-of-birth", out DateTime dateOfBirth)) { // "date-of-birth" is there, so set the star sign. var monthAndDay = new DateTime(1, dateOfBirth.Month, dateOfBirth.Day); foreach (var starSign in _starSigns) { if (monthAndDay > starSign.Start && monthAndDay < starSign.End) { // The star sign has been found, so set it in the // results. starSignData.StarSign = starSign.Name; break; } } } else { // "date-of-birth" is not there, so set the star sign to unknown. starSignData.StarSign = "Unknown"; } }
protected override void ProcessInternal(IFlowData data) { TestElementData elementData = data.GetOrAdd( ElementDataKeyTyped, (p) => new TestElementData(p)); int value = (int)data.GetEvidence()[EvidenceKeys[0]]; elementData.Result = value * 5; }
/// <summary> /// Process the client IP address by splitting the segments into an /// array /// </summary> /// <param name="data">FlowData to add the result to</param> protected override void ProcessInternal(IFlowData data) { SplitIpData elementData = (SplitIpData)data.GetOrAdd( ElementDataKeyTyped, (f) => base.CreateElementData(f)); string ip = ((string)data.GetEvidence()[EvidenceKeys[0]]); elementData.ClientIp = ip.Split('.', ':'); }
protected override void ProcessInternal(IFlowData data) { var monthAndDay = new DateTime(1, 1, 1); // Create a new IStarSignData, and cast to StarSignData so the 'setter' is available. StarSignData starSignData = (StarSignData)data.GetOrAdd(ElementDataKey, CreateElementData); bool validDateOfBirth = false; if (data.TryGetEvidence("cookie.date-of-birth", out string dateString)) { // "date-of-birth" is there, so parse it. string[] dateSections = dateString.Split('/'); try { monthAndDay = new DateTime( 1, int.Parse(dateSections[1]), int.Parse(dateSections[0])); validDateOfBirth = true; } catch (Exception) { } } if (validDateOfBirth) { // "date-of-birth" is valid, so set the star sign. foreach (var starSign in _starSigns) { if (monthAndDay > starSign.Start && monthAndDay < starSign.End) { // The star sign has been found, so set it in the // results. starSignData.StarSign = starSign.Name; break; } } // No need to run the client side code again. starSignData.DobJavaScript = new JavaScript(""); } else { // "date-of-birth" is not there, so set the star sign to unknown. starSignData.StarSign = "Unknown"; // Set the client side JavaScript to get the date of birth. starSignData.DobJavaScript = new JavaScript( "var dob = window.prompt('Enter your date of birth.','dd/mm/yyyy');" + "if (dob != null) {" + "document.cookie='date-of-birth='+dob;" + "location.reload();" + "}"); } }
/// <summary> /// Transform the data in the flow data instance into a /// JSON object. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if the supplied flow data is null. /// </exception> protected override void ProcessInternal(IFlowData data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } var elementData = data.GetOrAdd( ElementDataKeyTyped, CreateElementData); var jsonString = BuildJson(data); elementData.Json = jsonString; }
/// <summary> /// Transform the data in the flow data instance into a /// JSON object. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if the supplied flow data is null. /// </exception> protected override void ProcessInternal(IFlowData data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (_pipelineConfigs.TryGetValue(data.Pipeline, out PipelineConfig config) == false) { config = PopulateMetaDataCollections(data.Pipeline); config = _pipelineConfigs.GetOrAdd(data.Pipeline, config); } var elementData = data.GetOrAdd( ElementDataKeyTyped, CreateElementData); var jsonString = BuildJson(data, config); elementData.Json = jsonString; }
public void MultiEngineData_SimpleTest() { BuildEngine(false); IFlowData data = _pipeline.CreateFlowData(); EmptyEngineData engineData = data.GetOrAdd( _engine.ElementDataKeyTyped, (f) => new EmptyEngineData( _loggerFactory.CreateLogger <EmptyEngineData>(), f, _engine, null)); engineData.ValueOne = 0; engineData.ValueThree = 50; data.Process(); var result = data.Get <EmptyEngineData>(); Assert.AreEqual(1, result.ValueOne); Assert.AreEqual(50, result.ValueThree); }
/// <summary> /// Process the flow data /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> /// </param> protected override void ProcessInternal(IFlowData data) { ListSplitterElementData elementData = data.GetOrAdd( ElementDataKeyTyped, (p) => new ListSplitterElementData(p)); // Get the source string string source = (string)data.GetEvidence()[EvidenceKeys[0]]; // Split the source string using the configured delimiter. var results = source .Split(_delimiters, StringSplitOptions.RemoveEmptyEntries) .ToList(); elementData.Result = new List <string>(); // Iterate through the resulting strings, checking if they are // over the max length. // If any string is too long then it is split into chunks of // max length. for (int i = 0; i < results.Count; i++) { var result = results[i]; while (result.Length > _maxLength) { // Take the first _maxLength characters and add them // to the element data result. elementData.Result.Add(result.Remove(_maxLength)); // Remove the first _maxLength characters from the // string and repeat. result = result.Substring(_maxLength); } // Add the string to the element data result. if (result.Length > 0) { elementData.Result.Add(result); } } }
/// <summary> /// Build the JavaScript content and add it to the supplied /// <see cref="IFlowData"/> instance. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> instance to populate with the /// resulting <see cref="JavaScriptBuilderElementData"/> /// </param> /// <param name="jsonObject"> /// The JSON data object to include in the JavaScript. /// </param> /// <param name="supportsPromises"> /// True to build JavaScript that uses promises. False to /// build JavaScript that does not use promises. /// </param> /// <param name="url"> /// The callback URL for the JavaScript to send a request to /// when it has new evidence values to supply. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown if the supplied flow data is null. /// </exception> protected void BuildJavaScript(IFlowData data, string jsonObject, bool supportsPromises, Uri url) { if (data == null) { throw new ArgumentNullException(nameof(data)); } JavaScriptBuilderElementData elementData = (JavaScriptBuilderElementData) data.GetOrAdd( ElementDataKeyTyped, CreateElementData); // Try and get the requested object name from evidence. if (data.TryGetEvidence(Constants.EVIDENCE_OBJECT_NAME, out string objectName) == false || string.IsNullOrWhiteSpace(objectName)) { objectName = ObjName; } var ubdateEnabled = url != null && url.AbsoluteUri.Length > 0; JavaScriptResource javaScriptObj = new JavaScriptResource( objectName, jsonObject, supportsPromises, url, EnableCookies, ubdateEnabled); string content = _stubble.Render(_template, javaScriptObj.AsDictionary() /*, _renderSettings*/); string minifiedContent = content; if (_minify) { // Minimize the script. var ugly = Uglify.Js(content); if (ugly.HasErrors) { // If there were are errors then log them and // return the non-minified response. minifiedContent = content; if (_lastRequestWasError == false) { StringBuilder errorText = new StringBuilder(); errorText.AppendLine("Errors occurred when minifying JavaScript."); foreach (var error in ugly.Errors) { errorText.AppendLine($"{error.ErrorCode}: {error.Message}. " + $"Line(s) {error.StartLine}-{error.EndLine}. " + $"Column(s) {error.StartColumn}-{error.EndColumn}"); } errorText.AppendLine(content); Logger.LogError(errorText.ToString()); _lastRequestWasError = true; #pragma warning disable CS0618 // Type or member is obsolete // This usage should be replaced with the // CancellationToken implementation once it // is available. data.Stop = true; #pragma warning restore CS0618 // Type or member is obsolete } } else { minifiedContent = ugly.Code; } } elementData.JavaScript = minifiedContent; }
/// <summary> /// Private method that checks if the result is already in the cache /// or not. /// If it is then the result is added to 'data', if not then /// <see cref="ProcessEngine(IFlowData, T)"/> is called to do so. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> instance that provides the evidence /// and holds the result. /// </param> private void ProcessWithCache(IFlowData data) { T cacheResult = default(T); // If there is a cache then check if the result // is already in there. if (_cache != null) { try { cacheResult = (T)_cache[data]; } catch (InvalidCastException) { } } // If we don't have a result from the cache then // run through the normal processing. if (cacheResult == null) { // If the flow data already contains an entry for this // element's key then use it. Otherwise, create a new // aspect data instance and add it to the flow data. T aspectData = data.GetOrAdd(ElementDataKeyTyped, CreateElementData); if (aspectData.Engines.Contains(this) == false) { (aspectData as AspectDataBase).AddEngine(this); } // Start the engine processing if (LazyLoadingConfiguration != null) { // If lazy loading is configured then create a task // to do the processing and assign the task to the // aspect data property. var task = Task.Run(() => { ProcessEngine(data, aspectData); }); (aspectData as AspectDataBase).AddProcessTask(task); } else { // If not lazy loading, just start processing. ProcessEngine(data, aspectData); } // If there is a cache then add the result // of processing to the cache. if (_cache != null) { _cache.Put(data, data.GetFromElement(this)); } } else { // We have a result from the cache so add it // into the flow data. data.GetOrAdd(ElementDataKeyTyped, (f) => { return(cacheResult); }); } }
protected override void ProcessInternal(IFlowData data) { var sourceData = data.GetOrAdd(ElementDataKey, p => CreateElementData(p)); sourceData.PopulateFromDictionary(_propertyNameValuesToReturn); }
/// <summary> /// Build the JavaScript content and add it to the supplied /// <see cref="IFlowData"/> instance. /// </summary> /// <param name="data"> /// The <see cref="IFlowData"/> instance to populate with the /// resulting <see cref="JavaScriptBuilderElementData"/> /// </param> /// <param name="jsonObject"> /// The JSON data object to include in the JavaScript. /// </param> /// <param name="sessionId"> /// The session Id to use in the JavaScript response. /// </param> /// <param name="sequence"> /// The sequence value to use in the JavaScript response. /// </param> /// <param name="supportsPromises"> /// True to build JavaScript that uses promises. False to /// build JavaScript that does not use promises. /// </param> /// <param name="supportsFetch"> /// True to build JavaScript that makes use of the /// fetch API. Otherwise, the template will fall back to using /// XMLHttpRequest. /// </param> /// <param name="url"> /// The callback URL for the JavaScript to send a request to /// when it has new evidence values to supply. /// </param> /// <param name="parameters">The parameters to append to the URL</param> /// <exception cref="ArgumentNullException"> /// Thrown if the supplied flow data is null. /// </exception> protected void BuildJavaScript( IFlowData data, string jsonObject, string sessionId, int sequence, bool supportsPromises, bool supportsFetch, Uri url, string parameters) { if (data == null) { throw new ArgumentNullException(nameof(data)); } JavaScriptBuilderElementData elementData = (JavaScriptBuilderElementData) data.GetOrAdd( ElementDataKeyTyped, CreateElementData); string objectName = ObjName; // Try and get the requested object name from evidence. if (data.TryGetEvidence(Constants.EVIDENCE_OBJECT_NAME, out object objObjectName)) { objectName = objObjectName?.ToString() ?? ObjName; } var ubdateEnabled = url != null && url.AbsoluteUri.Length > 0; // This check won't be 100% fool-proof but it only needs to be // reasonably accurate and not take too long. var hasDelayedProperties = jsonObject != null && jsonObject.Contains("delayexecution"); JavaScriptResource javaScriptObj = new JavaScriptResource( objectName, jsonObject, sessionId, sequence, supportsPromises, supportsFetch, url, parameters, EnableCookies, ubdateEnabled, hasDelayedProperties); string content = _stubble.Render(_template, javaScriptObj.AsDictionary()); string minifiedContent = content; if (_minify) { // Minimize the script. var ugly = Uglify.Js(content); if (ugly.HasErrors) { // If there were are errors then log them and // return the non-minified response. minifiedContent = content; if (_lastRequestWasError == false) { StringBuilder errorText = new StringBuilder(); errorText.AppendLine("Errors occurred when minifying JavaScript."); foreach (var error in ugly.Errors) { errorText.AppendLine($"{error.ErrorCode}: {error.Message}. " + $"Line(s) {error.StartLine}-{error.EndLine}. " + $"Column(s) {error.StartColumn}-{error.EndColumn}"); } errorText.AppendLine(content); Logger.LogError(errorText.ToString()); _lastRequestWasError = true; #pragma warning disable CS0618 // Type or member is obsolete // This usage should be replaced with the // CancellationToken implementation once it // is available. data.Stop = true; #pragma warning restore CS0618 // Type or member is obsolete } } else { minifiedContent = ugly.Code; } } elementData.JavaScript = minifiedContent; }