/// <summary> /// THis is to split the HL loops appropriately /// </summary> /// <param name="edi"></param> /// <param name="loopID"></param> /// <param name="position"></param> /// <param name="value"></param> /// <returns></returns> public static List <String> LoopSplit(this string edi, EDILoop loopInfo, EDIDelim seperator) { string[] segments = edi.Split(seperator.Segment); bool inLoop = false; List <string> loops = new List <string>(); List <string> tmp = new List <string>(); foreach (string segment in segments) { if (segment.StartsWith(loopInfo.GetFormat())) { string[] elements = segment.Split(seperator.Element); if (elements[loopInfo.GetPosition()].Equals(loopInfo.GetSelectionValue())) { if (tmp.Count > 0) { loops.Add(String.Join("" + seperator.Segment, tmp)); tmp.Clear(); } inLoop = true; } } if (inLoop) { tmp.Add(segment); } } if (tmp.Count > 0) { loops.Add(String.Join("" + seperator.Segment, tmp)); } return(loops); }
public static List <string> TransactionSplit(this string edi, EDILoop loopInfo, EDIDelim delims) { if (String.IsNullOrWhiteSpace(loopInfo.GetSelectionValue())) { if (String.IsNullOrWhiteSpace(loopInfo.GetIgnoreStartID())) { return(edi.TransactionSplit(loopInfo.GetSplitFormat(), delims.Segment)); } return(edi.DoTransactionSplit(loopInfo, delims)); } return(edi.LoopSplit(loopInfo, delims)); }
internal string GetSegmentID(PropertyInfo pInfo) { if (pInfo.CanRead) { Attribute[] attrs = Attribute.GetCustomAttributes(pInfo); if (attrs.Any(x => x.GetType() == typeof(EDILoop))) { EDILoop currentLoop = ((EDILoop)attrs.FirstOrDefault(z => z.GetType() == typeof(EDILoop))); return(currentLoop.GetFormat()); } string segmentID = pInfo.PropertyType.Name.Replace("Seg", ""); if (segmentID.ToUpper().StartsWith("LIST")) { segmentID = pInfo.PropertyType.GetGenericArguments()[0].Name.Replace("Seg", ""); } return(segmentID); } return(""); }
public static List <string> DoTransactionSplit(this string edi, EDILoop loopInfo, EDIDelim seperators) { List <string> rtnVal = new List <string>(); string[] segments = edi.Split(seperators.Segment); List <string> tmp = new List <string>(); bool doCheck = true; int startSeg = 0; int endSeg = 0; //assumption is that this will be called when the first segment meets the initial criteria tmp.Add(segments[0]); for (int i = 1; i < segments.Count(); i++) { if (segments[i].StartsWith(loopInfo.GetFormat()) && doCheck) { rtnVal.Add(string.Join("" + seperators.Segment, tmp)); tmp.Clear(); } if (segments[i].StartsWith(loopInfo.GetIgnoreStartID())) { doCheck = false; } if (segments[i].StartsWith(loopInfo.GetIgnoreEndID())) { doCheck = true; } tmp.Add(segments[i]); } if (tmp.Count > 0) { rtnVal.Add(string.Join("" + seperators.Segment, tmp)); } return(rtnVal); }
/// <summary> /// THis is the recursive function that is called. /// </summary> /// <param name="ediData"></param> /// <param name="seperators"></param> internal void FromEDIString(string ediData, EDIDelim seperators) { string[] strSegments = ediData.Split(new char[] { seperators.Segment }, StringSplitOptions.RemoveEmptyEntries); //Hopefully allows us to determine if the segment even belongs in the current object. List <string> objSegments = GetAvailableSegments(); int p = 0; //TODO: How do we align the inbound to the object... for (int objPntr = 0; objPntr < GetType().GetProperties().Length; objPntr++) { PropertyInfo propertyInfo = GetType().GetProperties()[objPntr]; if (propertyInfo.CanRead) { Attribute[] attrs = Attribute.GetCustomAttributes(propertyInfo); bool IsGeneric = false; if (attrs.Any(x => x.GetType() == typeof(EDILoop))) { EDILoop currentLoop = ((EDILoop)attrs.FirstOrDefault(z => z.GetType() == typeof(EDILoop))); currentLoop.AdjustFormat(seperators.Element); //Check to see if the segment starts this way... //string segStart = currentLoop.GetFormat() + seperators.Element; if (strSegments[p].StartsWith(currentLoop.GetFormat())) { //This should be the amount of Segments we need to group together in order to split properly. int es = strSegments.Count() - p - currentLoop.GetEndSkip(); //we know that the current loop is at least one we want... //es cannot be less than 1 if (es == 0) { es = 1; } //TODO: Multiple altsegment ending ID's how to handle here... if (currentLoop.GetAltSegmentID().Any()) { for (int i = p + 1; i < strSegments.Count(); i++) { //if (strSegments[i].StartsWith(currentLoop.GetAltSegmentID())) if ( currentLoop.GetAltSegmentID() .Any(alt => strSegments[i].StartsWith(alt + seperators.Element))) { es = i - p; break; } } } //We need to determine the end point of the alt ending if present. List <string> loopValues = String.Join("" + seperators.Segment, strSegments, p, es) .TransactionSplit(currentLoop, seperators); //Foreach loop add since it is a list the "FromEDIString" object propertyValue = propertyInfo.GetValue(this, null); //This should always do the later but for testing have it here... if (propertyValue == null) { //How do we put this as the property value ConstructorInfo ctor = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes); object instance = ctor.Invoke(null); propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType), null); propertyValue = propertyInfo.GetValue(this, null); } if (IsPropertyACollection(propertyInfo)) { MethodInfo Addmethod = propertyValue.GetType().GetMethod("Add"); Type t = propertyValue.GetType().GetGenericArguments()[0]; //EDIBase call MethodInfo ediMethod = t.GetMethod("FromEDIString", internalFlags); foreach (string lValues in loopValues) { var tmp = t.GetConstructor(new Type[] {}).Invoke(new object[] {}); //Invoke the EDI string parser ediMethod.Invoke(tmp, new object[] { lValues, seperators }); //Add the new item to the list. Addmethod.Invoke(propertyValue, new object[] { tmp }); } } else { //This should only be called once... but we shall see... foreach (string lValues in loopValues) { MethodInfo ediMethod = propertyValue.GetType() .GetMethod("FromEDIString", internalFlags); ediMethod.Invoke(propertyValue, new object[] { lValues, seperators }); } } //p = strSegments.Count() - currentLoop.GetEndSkip(); p = p + es; } else { //If EDI file we are reading has an extra segment that is not part of the object //then we need to skip it and go on to the next one, while keeping our place //in the current file to properly unmarshal the rest of the file if (!IsValidSegment(strSegments[p], objSegments, objPntr)) { p++; objPntr--; } } } else { //Handle single and list of simple segments. string segmentID = propertyInfo.PropertyType.Name.Replace("Seg", ""); if (segmentID.ToUpper().StartsWith("LIST")) { segmentID = propertyInfo.PropertyType.GetGenericArguments()[0].Name.Replace("Seg", ""); if (propertyInfo.PropertyType.GetGenericArguments()[0].Name.StartsWith("Generic")) { IsGeneric = true; } } if (p > strSegments.Count() - 1) { break; } if (strSegments[p].StartsWith(segmentID) || IsGeneric) { //Actually Grab the class of what we are trying to do object propertyValue = propertyInfo.GetValue(this, null); if (propertyValue == null) { //How do we put this as the property value ConstructorInfo ctor = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes); object instance = ctor.Invoke(null); propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType), null); propertyValue = propertyInfo.GetValue(this, null); } //Collection of single objects if (IsPropertyACollection(propertyInfo)) { //This is the list of objects and function for the adding MethodInfo Addmethod = propertyValue.GetType().GetMethod("Add"); //THis is the type of object and the method we need plus the segment ID Type t = propertyValue.GetType().GetGenericArguments()[0]; MethodInfo ediMethod = t.GetMethod("FromEDIString", internalFlags); string segID = t.Name.Replace("Seg", ""); //Start looping through the segments while (strSegments[p].StartsWith(segID) || IsGeneric) { //Create an instance of the list object var tmp = t.GetConstructor(new Type[] {}).Invoke(new object[] {}); //Invoke the EDI string parser ediMethod.Invoke(tmp, new object[] { strSegments[p], seperators }); //Add the new item to the list. Addmethod.Invoke(propertyValue, new object[] { tmp }); p++; if ((p >= strSegments.Count()) || (IsGeneric && (p >= strSegments.Count() - 1))) { break; } } } else { //This didn't work so good.... but we are not loop through the segments of the base type.. if (propertyValue.GetType().BaseType == typeof(EDIBase)) { string inputValue = String.Join("" + seperators.Segment, strSegments, p, strSegments.Count() - 1); MethodInfo ediMethod = propertyValue.GetType() .GetMethod("FromEDIString", internalFlags); //This should always do the later but for testing have it here... ediMethod.Invoke(propertyValue, new object[] { inputValue, seperators }); p = (strSegments.Count() - 1); } else { //Grab the function we are going to use // Type[] paramTypes = _countMethodParams.Select(p => p.GetType()).ToArray(); MethodInfo method = propertyValue.GetType() .GetMethod("FromEDIString", internalFlags); //Invoke the function of that class on the class //strSegments.Add(method.Invoke(propertyValue, new object[] { '*' }).ToString()); method.Invoke(propertyValue, new object[] { strSegments[p], seperators }); p++; } } } else { //If EDI file we are reading has an extra segment that is not part of the object //then we need to skip it and go on to the next one, while keeping our place //in the current file to properly unmarshal the rest of the file if (!IsValidSegment(strSegments[p], objSegments, objPntr)) { p++; objPntr--; } } } } if (p > strSegments.Count() - 1) { break; } } }
//Works with straight EDIBase and SegmentBase values but is hard coded for seperators... public void FromEDIString(string ediData, ) { string[] strSegments = ediData.Split(new char[] { segmentSep }, StringSplitOptions.RemoveEmptyEntries); int p = 0; //TODO: How do we align the inbound to the object... foreach (PropertyInfo propertyInfo in GetType().GetProperties()) { if (propertyInfo.CanRead) { Attribute[] attrs = Attribute.GetCustomAttributes(propertyInfo); if (attrs.Any(x => x.GetType() == typeof(EDILoop))) { EDILoop currentLoop = ((EDILoop)attrs.FirstOrDefault(z => z.GetType() == typeof(EDILoop))); //Check to see if the segment starts this way... if (strSegments[p].StartsWith(currentLoop.GetFormat())) { //This should be the amount of Segments we need to group together in order to split properly. int es = strSegments.Count() - p - currentLoop.GetEndSkip(); if (!String.IsNullOrWhiteSpace(currentLoop.GetAltSegmentID())) { for (int i = p + 1; i < strSegments.Count(); i++) { if (strSegments[i].StartsWith(currentLoop.GetAltSegmentID())) { es = i - p; break; } } } //We need to determine the end point of the alt ending if present. List <string> loopValues = String.Join("" + segmentSep, strSegments, p, es) .TransactionSplit(currentLoop, segmentSep); //Foreach loop add since it is a list the "FromEDIString" object propertyValue = propertyInfo.GetValue(this, null); //This should always do the later but for testing have it here... if (propertyValue == null) { //How do we put this as the property value ConstructorInfo ctor = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes); object instance = ctor.Invoke(null); propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType), null); propertyValue = propertyInfo.GetValue(this, null); } MethodInfo Addmethod = propertyValue.GetType().GetMethod("Add"); Type t = propertyValue.GetType().GetGenericArguments()[0]; MethodInfo ediMethod = t.GetMethod("FromEDIString"); foreach (string lValues in loopValues) { var tmp = t.GetConstructor(new Type[] {}).Invoke(new object[] {}); //Invoke the EDI string parser ediMethod.Invoke(tmp, new object[] { lValues, segmentSep }); //Add the new item to the list. Addmethod.Invoke(propertyValue, new object[] { tmp }); } p = strSegments.Count() - currentLoop.GetEndSkip(); } } else { //Handle single and list of simple segments. string segmentID = propertyInfo.PropertyType.Name.Replace("Seg", ""); if (segmentID.ToUpper().StartsWith("LIST")) { segmentID = propertyInfo.PropertyType.GetGenericArguments()[0].Name.Replace("Seg", ""); //segmentID = propertyInfo.PropertyType.generictype[0].Name; } if (strSegments[p].StartsWith(segmentID)) { //Actually Grab the class of what we are trying to do object propertyValue = propertyInfo.GetValue(this, null); if (propertyValue == null) { //How do we put this as the property value ConstructorInfo ctor = propertyInfo.PropertyType.GetConstructor(System.Type.EmptyTypes); object instance = ctor.Invoke(null); propertyInfo.SetValue(this, Convert.ChangeType(instance, propertyInfo.PropertyType), null); propertyValue = propertyInfo.GetValue(this, null); } //Collection of single objects if (IsPropertyACollection(propertyInfo)) { //This is the list of objects and function for the adding MethodInfo Addmethod = propertyValue.GetType().GetMethod("Add"); //THis is the type of object and the method we need plus the segment ID Type t = propertyValue.GetType().GetGenericArguments()[0]; MethodInfo ediMethod = t.GetMethod("FromEDIString", new Type[] { typeof(string) }); string segID = t.Name.Replace("Seg", ""); //Start looping through the segments while (strSegments[p].StartsWith(segID)) { //Create an instance of the list object var tmp = t.GetConstructor(new Type[] {}).Invoke(new object[] {}); //Invoke the EDI string parser ediMethod.Invoke(tmp, new object[] { strSegments[p] }); //Add the new item to the list. Addmethod.Invoke(propertyValue, new object[] { tmp }); p++; if (p >= strSegments.Count()) { break; } } } else { //This didn't work so good.... but we are not loop through the segments of the base type.. if (propertyValue.GetType().BaseType == typeof(EDIBase)) { string inputValue = String.Join("" + segmentSep, strSegments, p, strSegments.Count() - 1); MethodInfo ediMethod = propertyValue.GetType().GetMethod("FromEDIString"); //This should always do the later but for testing have it here... ediMethod.Invoke(propertyValue, new object[] { inputValue, segmentSep }); p = (strSegments.Count() - 1); } else { //Grab the function we are going to use // Type[] paramTypes = _countMethodParams.Select(p => p.GetType()).ToArray(); MethodInfo method = propertyValue.GetType() .GetMethod("FromEDIString", new Type[] { typeof(string) }); //Invoke the function of that class on the class //strSegments.Add(method.Invoke(propertyValue, new object[] { '*' }).ToString()); method.Invoke(propertyValue, new object[] { strSegments[p] }); p++; } } } } } if (p > strSegments.Count() - 1) { break; } } }