Skip to content

Commit 3553658

Browse files
Merge pull request #75 from xcomponent/ISSUE-74
ISSUE-74 : Fix when parsing an XCApi containing different components with the same stateMachine name
2 parents 8826a68 + 0552bbf commit 3553658

5 files changed

Lines changed: 116 additions & 81 deletions

File tree

ReactiveXComponent/Configuration/XCApiTags.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static class XCApiTags
1515
public const string EventCode = "eventCode";
1616
public const string ComponentCode = "componentCode";
1717
public const string StateMachineCode = "stateMachineCode";
18+
public const string StateMachine = "stateMachine";
1819
public const string Topic = "topic";
1920
public const string Subscribe = "subscribe";
2021
public const string EventType = "eventType";
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace ReactiveXComponent.Parser
2+
{
3+
public class StateMachineInfo
4+
{
5+
public string StateMachineName { get; }
6+
public int StateMachineCode { get; }
7+
8+
public StateMachineInfo(string stateMachineName, int stateMachineCode)
9+
{
10+
StateMachineName = stateMachineName;
11+
StateMachineCode = stateMachineCode;
12+
}
13+
}
14+
}

ReactiveXComponent/Parser/XCApiConfigParser.cs

Lines changed: 99 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,69 @@ namespace ReactiveXComponent.Parser
1111
{
1212
public class XCApiConfigParser : IXCApiConfigParser
1313
{
14-
private XCApiDescription _xcApiDescription;
15-
16-
private Dictionary<string, int> _componentCodeByComponent;
17-
private Dictionary<string, int> _stateMachineCodeByStateMachine;
18-
private Dictionary<string, int> _eventCodeByEvent;
19-
private Dictionary<TopicIdentifier, string> _publisherTopicByIdentifier;
20-
private Dictionary<TopicIdentifier, string> _subscriberTopicByIdentifier;
21-
private Dictionary<long, string> _snapshotTopicByComponent;
22-
14+
private XCApiDescription _xcApiDescription;
2315
private XNamespace _xc;
16+
private Dictionary<string, int> _eventCodeByEventRepository;
17+
private Dictionary<TopicIdentifier, string> _publisherTopicByIdentifierRepository;
18+
private Dictionary<TopicIdentifier, string> _subscriberTopicByIdentifierRepository;
19+
private Dictionary<long, string> _snapshotTopicByComponentRepository;
20+
private readonly Dictionary<string, List<StateMachineInfo>> _stateMachineInfoByComponentRepository =
21+
new Dictionary<string, List<StateMachineInfo>>();
22+
private readonly Dictionary<string, int> _componentCodeByComponentNameRepository = new Dictionary<string, int>();
23+
2424

2525
public void Parse(Stream xcApiStream)
2626
{
2727
var reader = XmlReader.Create(xcApiStream);
2828
_xcApiDescription = new XCApiDescription(reader);
2929
_xc = "http://xcomponent.com/DeploymentConfig.xsd";
3030

31-
_componentCodeByComponent = CreateComponentCodeByNameRepository(_xcApiDescription.GetComponentsNode());
32-
_stateMachineCodeByStateMachine = CreateStateMachineCodeByNameRepository(_xcApiDescription.GetStateMachinesNode());
33-
_eventCodeByEvent = CreateEventCodeByEventRepository(_xcApiDescription.GetPublishersNode());
34-
_publisherTopicByIdentifier = CreatePublisherTopicByComponentAndStateMachineRepository(_xcApiDescription.GetPublishersNode());
35-
_subscriberTopicByIdentifier = CreateConsumerTopicByComponentAndStateMachineAndRepository(_xcApiDescription.GetConsumersNode());
36-
_snapshotTopicByComponent = CreateSnapshotTopicByComponentRepository(_xcApiDescription.GetSnapshotsNode()); ;
31+
ParseComponentNodes(_xcApiDescription.GetComponentsNode());
32+
_eventCodeByEventRepository = CreateEventCodeByEventRepository(_xcApiDescription.GetPublishersNode());
33+
_publisherTopicByIdentifierRepository =
34+
CreatePublisherTopicByComponentAndStateMachineRepository(_xcApiDescription.GetPublishersNode());
35+
_subscriberTopicByIdentifierRepository =
36+
CreateConsumerTopicByComponentAndStateMachineRepository(_xcApiDescription.GetConsumersNode());
37+
_snapshotTopicByComponentRepository = CreateSnapshotTopicByComponentRepository(_xcApiDescription.GetSnapshotsNode());
3738
}
3839

39-
private Dictionary<string, int> CreateComponentCodeByNameRepository(IEnumerable<XElement> components)
40+
private void ParseComponentNodes(IEnumerable<XElement> components)
4041
{
41-
Dictionary<string, int> componentCodeByNameRepo = new Dictionary<string, int>();
42-
4342
foreach (XElement component in components)
4443
{
45-
AddComponentToRepository(componentCodeByNameRepo, component);
44+
var componentName = component.Attribute(XCApiTags.Name)?.Value;
45+
var componentCode = component.Attribute(XCApiTags.Id)?.Value;
46+
47+
if (!string.IsNullOrEmpty(componentName) && !string.IsNullOrEmpty(componentCode))
48+
{
49+
_componentCodeByComponentNameRepository.Add(componentName, Convert.ToInt32(componentCode));
50+
51+
ParseStateMachineNodes(component, componentName);
52+
}
4653
}
47-
return componentCodeByNameRepo;
4854
}
4955

50-
private void AddComponentToRepository(Dictionary<string, int> repository, XElement component)
51-
{
52-
repository.Add(component.Attribute(XCApiTags.Name).Value, Convert.ToInt32(component.Attribute(XCApiTags.Id).Value));
53-
}
54-
55-
private Dictionary<string, int> CreateStateMachineCodeByNameRepository(IEnumerable<XElement> stateMachines)
56+
private void ParseStateMachineNodes(XElement component, string componentName)
5657
{
57-
Dictionary<string, int> stateMachineCodeRepo = new Dictionary<string, int>();
58-
foreach (XElement stateMachine in stateMachines)
58+
if (_stateMachineInfoByComponentRepository.ContainsKey(componentName)) return;
59+
60+
var stateMachines = component.Descendants(_xc + XCApiTags.StateMachine);
61+
var statemachineInfoList = new List<StateMachineInfo>
62+
(
63+
stateMachines
64+
.Where(stateMachine =>
65+
!string.IsNullOrEmpty(stateMachine?.Attribute(XCApiTags.Name)?.Value)
66+
&& !string.IsNullOrEmpty(stateMachine.Attribute(XCApiTags.Id)?.Value))
67+
.Select(stateMachine =>
68+
new StateMachineInfo(stateMachine.Attribute(XCApiTags.Name)?.Value,
69+
Convert.ToInt32(stateMachine.Attribute(XCApiTags.Id)?.Value))
70+
).ToList()
71+
);
72+
73+
if (statemachineInfoList.Any())
5974
{
60-
stateMachineCodeRepo.Add(stateMachine.Attribute(XCApiTags.Name).Value, Convert.ToInt32(stateMachine.Attribute(XCApiTags.Id).Value));
75+
_stateMachineInfoByComponentRepository.Add(componentName, statemachineInfoList);
6176
}
62-
return stateMachineCodeRepo;
6377
}
6478

6579
private Dictionary<string, int> CreateEventCodeByEventRepository(IEnumerable<XElement> publishNodes)
@@ -75,14 +89,19 @@ private Dictionary<string, int> CreateEventCodeByEventRepository(IEnumerable<XEl
7589

7690
private void AddEventCodeToRepository(Dictionary<string, int> repository, XElement node)
7791
{
78-
if (node?.Attribute(XCApiTags.EventName)?.Value != null && !repository.ContainsKey(node.Attribute(XCApiTags.EventName).Value))
92+
var eventName = node?.Attribute(XCApiTags.EventName)?.Value;
93+
var eventCode = node?.Attribute(XCApiTags.EventCode)?.Value;
94+
95+
if (!string.IsNullOrEmpty(eventName)
96+
&& !repository.ContainsKey(eventName)
97+
&& !string.IsNullOrEmpty(eventCode))
7998
{
80-
repository.Add(node.Attribute(XCApiTags.EventName).Value,
81-
Convert.ToInt32(node.Attribute(XCApiTags.EventCode).Value));
99+
repository.Add(eventName, Convert.ToInt32(eventCode));
82100
}
83101
}
84102

85-
private Dictionary<TopicIdentifier, string> CreatePublisherTopicByComponentAndStateMachineRepository(IEnumerable<XElement> publishNodes)
103+
private Dictionary<TopicIdentifier, string> CreatePublisherTopicByComponentAndStateMachineRepository(
104+
IEnumerable<XElement> publishNodes)
86105
{
87106
Dictionary<TopicIdentifier, string> topicByIdentifierRepo = new Dictionary<TopicIdentifier, string>();
88107

@@ -93,7 +112,8 @@ private Dictionary<TopicIdentifier, string> CreatePublisherTopicByComponentAndSt
93112
return topicByIdentifierRepo;
94113
}
95114

96-
private Dictionary<TopicIdentifier, string> CreateConsumerTopicByComponentAndStateMachineAndRepository(IEnumerable<XElement> subscribeNodes)
115+
private Dictionary<TopicIdentifier, string> CreateConsumerTopicByComponentAndStateMachineRepository(
116+
IEnumerable<XElement> subscribeNodes)
97117
{
98118
Dictionary<TopicIdentifier, string> topicByIdentifierRepo = new Dictionary<TopicIdentifier, string>();
99119

@@ -109,67 +129,64 @@ private void AddTopicToRepository(Dictionary<TopicIdentifier, string> repository
109129
var componentCode = Convert.ToInt64(node?.Attribute(XCApiTags.ComponentCode)?.Value);
110130
var stateMachineCode = Convert.ToInt64(node?.Attribute(XCApiTags.StateMachineCode)?.Value);
111131
var topicType = node?.Attribute(XCApiTags.TopicType)?.Value;
112-
132+
var topicValue = node?.Descendants(_xc + XCApiTags.Topic).FirstOrDefault()?.Value;
113133
var topicIdentifier = new TopicIdentifier(componentCode, stateMachineCode, topicType);
114-
115-
if (!repository.ContainsKey(topicIdentifier))
134+
135+
if (!repository.ContainsKey(topicIdentifier) && !string.IsNullOrEmpty(topicValue))
116136
{
117-
repository.Add(topicIdentifier, node?.Descendants(_xc + XCApiTags.Topic).FirstOrDefault().Value);
137+
repository.Add(topicIdentifier, topicValue);
118138
}
119-
}
120-
139+
}
140+
121141
private Dictionary<long, string> CreateSnapshotTopicByComponentRepository(IEnumerable<XElement> snapshotNodes)
122142
{
123-
Dictionary<long, string> SnapshotTopicByComponentRepo = new Dictionary<long, string>();
124-
foreach (XElement node in snapshotNodes)
143+
var snapshotTopicByComponentRepo = new Dictionary<long, string>();
144+
foreach (var node in snapshotNodes)
125145
{
126-
AddSnapshotTopicToRepository(SnapshotTopicByComponentRepo, node);
146+
AddSnapshotTopicToRepository(snapshotTopicByComponentRepo, node);
127147
}
128-
return SnapshotTopicByComponentRepo;
148+
return snapshotTopicByComponentRepo;
129149
}
130150

131-
private void AddSnapshotTopicToRepository(Dictionary<long, string> repository, XElement node)
151+
private void AddSnapshotTopicToRepository(IDictionary<long, string> repository, XElement node)
132152
{
133153
var componentCode = Convert.ToInt64(node?.Attribute(XCApiTags.ComponentCode)?.Value);
134-
135-
if (!repository.ContainsKey(componentCode))
154+
var snapshotTopic = node?.Descendants(_xc + XCApiTags.Topic).FirstOrDefault()?.Value;
155+
156+
if (!repository.ContainsKey(componentCode) && !string.IsNullOrEmpty(snapshotTopic))
136157
{
137-
repository.Add(componentCode, node?.Descendants(_xc + XCApiTags.Topic).FirstOrDefault().Value);
158+
repository.Add(componentCode, snapshotTopic);
138159
}
139160
}
140161

141162
public string GetConnectionType()
142163
{
143164
var commmunicationNode = _xcApiDescription.GetCommunicationNode()?.FirstOrDefault();
144165

145-
if (commmunicationNode != null)
146-
{
147-
var communicationChildElements = commmunicationNode.Elements().ToList();
166+
var communicationChildElements = commmunicationNode?.Elements().ToList();
148167

149-
if (communicationChildElements != null && communicationChildElements.Count == 1)
150-
{
151-
var connection = communicationChildElements.FirstOrDefault();
152-
return connection.Name.LocalName;
153-
}
168+
if (communicationChildElements != null && communicationChildElements.Count == 1)
169+
{
170+
var connection = communicationChildElements.FirstOrDefault();
171+
return connection?.Name.LocalName;
154172
}
155173

156174
return string.Empty;
157175
}
158176

159177
public string GetSerializationType()
160178
{
161-
var serialisation = _xcApiDescription.GetSerializationNode()?.FirstOrDefault()?.Value;
162-
return serialisation;
179+
return _xcApiDescription.GetSerializationNode()?.FirstOrDefault()?.Value;
163180
}
164181

165182
public BusDetails GetBusDetails()
166183
{
167184
XElement busInfos = _xcApiDescription.GetBusNode()?.FirstOrDefault();
168185
var busDetails = new BusDetails(
169-
busInfos?.Attribute("user")?.Value,
170-
busInfos?.Attribute("password")?.Value,
171-
busInfos?.Attribute("host")?.Value,
172-
Convert.ToInt32(busInfos?.Attribute("port")?.Value));
186+
busInfos?.Attribute("user")?.Value,
187+
busInfos?.Attribute("password")?.Value,
188+
busInfos?.Attribute("host")?.Value,
189+
Convert.ToInt32(busInfos?.Attribute("port")?.Value));
173190

174191
return busDetails;
175192
}
@@ -186,32 +203,34 @@ public WebSocketEndpoint GetWebSocketEndpoint()
186203
}
187204

188205
var webSocketEndpoint = new WebSocketEndpoint(
189-
websocketInfos?.Attribute("name")?.Value,
190-
websocketInfos?.Attribute("host")?.Value,
191-
websocketInfos?.Attribute("port")?.Value,
192-
webSocketType);
206+
websocketInfos?.Attribute("name")?.Value,
207+
websocketInfos?.Attribute("host")?.Value,
208+
websocketInfos?.Attribute("port")?.Value,
209+
webSocketType);
193210

194211
return webSocketEndpoint;
195212
}
196213

197214
public int GetComponentCode(string component)
198215
{
199216
int componentCode;
200-
_componentCodeByComponent.TryGetValue(component, out componentCode);
217+
_componentCodeByComponentNameRepository.TryGetValue(component, out componentCode);
201218
return componentCode;
202219
}
203220

204221
public int GetStateMachineCode(string component, string stateMachine)
205222
{
206-
int stateMachineCode = 0;
207-
_stateMachineCodeByStateMachine?.TryGetValue(stateMachine, out stateMachineCode);
208-
return stateMachineCode;
223+
if (!_stateMachineInfoByComponentRepository.ContainsKey(component)) return 0;
224+
225+
var stateMachineInfo = _stateMachineInfoByComponentRepository[component]
226+
?.FirstOrDefault(stmInfo => stmInfo.StateMachineName.Equals(stateMachine));
227+
return stateMachineInfo?.StateMachineCode ?? 0;
209228
}
210229

211230
public int GetPublisherEventCode(string eventName)
212231
{
213232
int eventCode;
214-
_eventCodeByEvent.TryGetValue(eventName, out eventCode);
233+
_eventCodeByEventRepository.TryGetValue(eventName, out eventCode);
215234
return eventCode;
216235
}
217236

@@ -222,17 +241,17 @@ public string GetPublisherTopic(string component, string stateMachine)
222241
var stateMachineCode = GetStateMachineCode(component, stateMachine);
223242
var topicId = new TopicIdentifier(componentCode, stateMachineCode, XCApiTags.Output);
224243

225-
_publisherTopicByIdentifier.TryGetValue(topicId, out publisherTopic);
244+
_publisherTopicByIdentifierRepository.TryGetValue(topicId, out publisherTopic);
226245
return publisherTopic;
227246
}
228247

229248
public string GetPublisherTopic(long componentCode, long stateMachineCode)
230249
{
231250
string publisherTopic;
232-
var topicId = new TopicIdentifier(componentCode, stateMachineCode, XCApiTags.Output);
233-
234-
_publisherTopicByIdentifier.TryGetValue(topicId, out publisherTopic);
235-
251+
var topicId = new TopicIdentifier(componentCode, stateMachineCode, XCApiTags.Output);
252+
253+
_publisherTopicByIdentifierRepository.TryGetValue(topicId, out publisherTopic);
254+
236255
return publisherTopic;
237256
}
238257

@@ -243,16 +262,16 @@ public string GetSubscriberTopic(string component, string stateMachine)
243262
var stateMachineCode = GetStateMachineCode(component, stateMachine);
244263
var topicId = new TopicIdentifier(componentCode, stateMachineCode, XCApiTags.Input);
245264

246-
_subscriberTopicByIdentifier.TryGetValue(topicId, out subscriberTopic);
265+
_subscriberTopicByIdentifierRepository.TryGetValue(topicId, out subscriberTopic);
247266
return subscriberTopic;
248267
}
249268

250269
public string GetSnapshotTopic(string component)
251270
{
252271
string snapshotTopic;
253272
var componentCode = GetComponentCode(component);
254-
_snapshotTopicByComponent.TryGetValue(componentCode, out snapshotTopic);
273+
_snapshotTopicByComponentRepository.TryGetValue(componentCode, out snapshotTopic);
255274
return snapshotTopic;
256275
}
257276
}
258-
}
277+
}

ReactiveXComponent/ReactiveXComponent.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
<Compile Include="Connection\IXCSubscriber.cs" />
9999
<Compile Include="Connection\IXCConnection.cs" />
100100
<Compile Include="Parser\IXCApiConfigParser.cs" />
101+
<Compile Include="Parser\StateMachineInfo.cs" />
101102
<Compile Include="Parser\XCApiDescription.cs" />
102103
<Compile Include="Connection\IXCPublisher.cs" />
103104
<Compile Include="Connection\IXCSession.cs" />
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
<packages>
33
<package id="Cake" version="0.23.0" />
44
<package id="XComponent.MSBuild.Tasks" version="1.0.0" />
5-
</packages>
5+
</packages>

0 commit comments

Comments
 (0)