-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathInetermediateFormatReader.cs
More file actions
123 lines (102 loc) · 4.64 KB
/
Copy pathInetermediateFormatReader.cs
File metadata and controls
123 lines (102 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System.Collections.Generic;
using System.Linq;
using EdiEngine.Common.Definitions;
using EdiEngine.Runtime;
using EdiEngine.Validation;
namespace EdiEngine
{
public abstract class InetermediateFormatReader : MapReader
{
protected EdiTrans Trans;
protected EdiLoop CurrentLoopInstance;
protected MapLoop CurrentLoopDef;
protected MapBaseEntity CurrentEntityDef;
protected InetermediateFormatReader(MapLoop map)
{
CurrentLoopDef = map;
}
protected abstract EdiIntermediateEntity ReadIntermediateTree(string rawData);
public virtual EdiTrans ReadToEnd(string rawData)
{
Trans = new EdiTrans(CurrentLoopDef);
CurrentLoopInstance = Trans;
CurrentLoopInstance.Definition = CurrentLoopDef;
EdiIntermediateEntity intermediateTree = ReadIntermediateTree(rawData);
ParseTree(intermediateTree);
return Trans;
}
protected virtual void ParseTree(EdiIntermediateEntity intermediateStructure)
{
foreach (EdiIntermediateEntity ent in intermediateStructure.Children)
{
switch (ent.EntityType)
{
case TokenContextType.Loop:
SetMapContext(ent.Name);
ParseTree(ent);
break;
case TokenContextType.Segment:
SetMapContext(ent.Name);
if (ent.Parent != null && !ent.Parent.Name.Equals(CurrentLoopDef.Name))
{
ValidationError err = new ValidationError()
{
Message = $"Unexpected Segment at {ent.Parent.Name} > {ent.Name}."
};
Trans.ValidationErrors.Add(err);
}
List<string> segParts = new List<string> { ent.Name };
segParts.AddRange(ent.Children.Select(el => el.ToString()));
EdiSegment seg = ProcessSegment(CurrentEntityDef, segParts.ToArray(), -1, EdiInterchange.DefaultCompositeSeparator, Trans);
CurrentLoopInstance.Content.Add(seg);
break;
}
}
}
//TODO:Refactor to make same code base with EdiMapReader.ProcessRawSegment
protected void SetMapContext(string name)
{
List<AllowedEntitity> allowedEntities = GetNextAllowedEntities(CurrentLoopDef);
if (allowedEntities.All(e => e.Entity.Name != name))
{
string expected = string.Join(", ", allowedEntities.Select(e => e.Entity.Name).ToList());
string msgPart = allowedEntities.Count > 1 ? "Expected one of" : "Expected";
ValidationError err = new ValidationError()
{
Message = $"Unexpected Segment. {msgPart} {expected}. Found {name}."
};
Trans.ValidationErrors.Add(err);
return;
}
AllowedEntitity ae = allowedEntities.FirstOrDefault(e => e.Entity.Name == name);
if (ae?.Entity is MapSegment)
{
ae.Entity.OccuredTimes++;
CurrentLoopDef = ae.LoopContext;
CurrentLoopDef.CurrentPos = CurrentLoopDef.Content.IndexOf(ae.Entity);
while (((MapLoop)CurrentLoopInstance.Definition) != ae.LoopContext && CurrentLoopInstance.Parent != null)
{
CurrentLoopInstance = CurrentLoopInstance.Parent;
}
CurrentEntityDef = ae.Entity;
}
else if (ae?.Entity is MapLoop)
{
//find loop definition in map and reset counters
ae.LoopContext.CurrentPos = ae.LoopContext.Content.IndexOf(ae.Entity);
CurrentLoopDef = (MapLoop)ae.Entity;
CurrentLoopDef.CurrentPos = 0;
CurrentLoopDef.OccuredTimes++;
CurrentLoopDef.Content.ForEach(c => c.OccuredTimes = 0);
////create new loop instance and add to transaction
while (((MapLoop)CurrentLoopInstance.Definition) != ae.LoopContext && CurrentLoopInstance.Parent != null)
{
CurrentLoopInstance = CurrentLoopInstance.Parent;
}
var newLoop = new EdiLoop(ae.Entity, CurrentLoopInstance);
CurrentLoopInstance.Content.Add(newLoop);
CurrentLoopInstance = newLoop;
}
}
}
}