/// <summary> /// This function is called for litmustest functions specified in the FeedFileMap. /// </summary> /// <param name="row">The raw data row.</param> /// <param name="map">An IMethodMap that describes how to perform the Litmus Test. /// </param> /// <returns>True, if the row passed the test, false otherwise.</returns> bool PerformLitmusTest(IList<string> row, IMethodMap map) { if (String.IsNullOrEmpty(map.MethodTag)) { throw new Exception( String.Format("TransformRow - have method {0}, but no methodTag", map.Method)); } if (!LitmusTestResolvers.ContainsKey(map.MethodTag)) { throw new Exception( String.Format("PerformLitmusTest - methodTag {0} for" + " method {1} missing from map of LitmusTestResolvers - config error", map.MethodTag, map.Method)); } var args = ProcessingHelper.ParseMethodArguments(row, map, Lookups); var method = LitmusTestResolvers[map.MethodTag].ResolveLitmusTest(map.Method); try { return method(Lookups, ExistenceObjects, args); } catch (Exception ex) { throw new Exception( String.Format("PerformLitmusTest - transformation " + "function {0} incorrectly threw an error {1} - this is a " + "fatal bug in the litmus test function code", map.Method, ex.Message)); } }
/// <summary> /// This function is called for PostRowProcessor methods specified in the FeedFileMap. /// </summary> /// <param name="loadNumber"></param> /// <param name="row">The raw data row.</param> /// <param name="rowInProgress">The completed output row.</param> /// <param name="map">An IMethodMap that describes how to perform the PostRowProcessor. /// </param> void InvokePostRowProcessor(int loadNumber, IList<string> row, IDictionary<string, string> rowInProgress, IMethodMap map) { if (String.IsNullOrEmpty(map.MethodTag)) { throw new Exception( String.Format("InvokePostRowProcessor - have method {0}, but no methodTag", map.Method)); } if (!PostRowProcessorResolvers.ContainsKey(map.MethodTag)) { throw new Exception( String.Format("InvokePostRowProcessor - methodTag {0} for" + " method {1} missing from map of InvokePostRowProcessorResolvers - " + "config error", map.MethodTag, map.Method)); } var args = ProcessingHelper.ParseMethodArguments(row, map, Lookups); var method = PostRowProcessorResolvers[map.MethodTag] .ResolvePostRowProcessor(map.Method); try { method(loadNumber, Lookups, ExistenceObjects, rowInProgress, args); } catch (Exception ex) { throw new Exception( String.Format("InvokePostRowProcessor - " + "method {0} incorrectly threw an error {1} - this is a fatal bug in the " + "postRowProcessor method code", map.Method, ex.Message)); } }
/// <summary> /// ProcessLookups examines the map to determine if lookups are being specified. If /// not, it just returns the values. If so, it uses the ILookup object specifed, using /// the source values as inputs to the lookup, and returning the indirected values. /// </summary> /// <param name="rowValues">The parsed raw input row.</param> /// <param name="map">The map that specifies the lookup to use.</param> /// <param name="lookups">The collection of lookup objects.</param> /// <returns>A list of indirected value, or (if no lookup), the original values. /// </returns> public static IList<string> ProcessLookups(IList<string> rowValues, IMethodMap map, IDictionary<string, ILookup> lookups) { if (!String.IsNullOrEmpty(map.Lookup)) { if (!lookups.ContainsKey(map.Lookup)) { throw new Exception( String.Format("ProcessLookups - no lookup with name {0}", map.Lookup)); } // Find the appropriate lookup object. var lookup = lookups[map.Lookup]; var lookedUpVals = new List<string>(); foreach (var rowVal in rowValues) { // Use the value as a key into a lookup, and use the looked-up value. lookedUpVals.Add(lookup.LookupValue(rowVal)); } return lookedUpVals; } return rowValues; }
/// <summary> /// This is a helper function that enables using lookups with either values from the /// source columns, or constants in the feed map as a key. All processed columns /// go through ProcessLookups, one way or another; this path is for the two cases when /// no method is specified (constant in feedmap and srcColumns). /// </summary> /// <param name="value">The value to process.</param> /// <param name="map">The map for this data item.</param> /// <param name="lookups">The global lookups collection.</param> /// <returns>A looked up value, if lookup exists for this map, or just returns the /// original passed in value, otherwsie.</returns> static string ProcessSingleValueWithLookupsIfSpecified(string value, IMethodMap map, IDictionary<string, ILookup> lookups) { IList<string> list = new List<string>(); // ProcessLookups takes a list. list.Add(value); list = ProcessLookups(list, map, lookups); return list[0]; }
/// <summary> /// For a given sourcevaluemap, the optional 'srcColumns' attribute describes a comma- /// separated list of integer column indices. This method will look up and return /// those values as a list of strings. /// </summary> /// <returns>The list of string arguments to the transform method</returns> /// <param name="row">Input row data from the parser.</param> /// <param name="map">The map that describes this transform.</param> /// <param name="lookups">List of lookups.</param> public static IList<string> ParseMethodArguments(IList<string> row, IMethodMap map, IDictionary<string, ILookup> lookups) { // Parse out list of args for Method. IList<string> args = new List<string>(); if (!String.IsNullOrEmpty(map.SrcColumns)) { var tokens = map.SrcColumns.Split(','); foreach (var token in tokens) { int iCol; if (!Int32.TryParse(token, out iCol)) { throw new Exception( String.Format("TransformRow - token {0} not parseable as int", token)); } if (iCol >= row.Count) { throw new Exception(String.Format("TransformRow - parsed " + "column arg {0} from config, but data row from " + "parser is only {1} columns wide", iCol, row.Count)); } args.Add(row[iCol].Trim()); } } // Process any optional lookups. args = ProcessLookups(args, map, lookups); // If we've gotten to this point and no arguments have been generated, generate // a single empty string. It can be used by methods like DefaultToUSCountryId() // as a sentinal that there's nothing in the feed for a given type of data. if (args.Count == 0) { args.Add(String.Empty); } return args; }