1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sourceforge.jarduino.message;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import net.sourceforge.jarduino.ArduinoException;
25 import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrClass;
26 import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrType;
27 import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
28
29
30
31
32 public class ArduinoAttributes {
33
34
35
36 static final String MARKER = "BA_";
37
38
39
40
41 static final String MARKER_DEF = "BA_DEF_";
42
43
44
45
46 static final String MARKER_DEFAULT = "BA_DEF_DEF_";
47
48
49
50
51 static final String MARKER_REL = MARKER + ArduinoAttribute.REL_MARKER;
52
53
54
55
56 static final String MARKER_REL_DEF = MARKER_DEF + ArduinoAttribute.REL_MARKER;
57
58
59
60
61 static final String MARKER_REL_DEFAULT = MARKER_DEFAULT + ArduinoAttribute.REL_MARKER;
62
63
64
65
66 private final Map<String, ArduinoAttribute> theAttributes;
67
68
69
70
71 ArduinoAttributes() {
72
73 theAttributes = new HashMap<>();
74 }
75
76
77
78
79
80 public List<ArduinoAttribute> getAttributes() {
81 return new ArrayList<>(theAttributes.values());
82 }
83
84
85
86
87
88
89 public ArduinoAttribute getAttributeForName(final String pName) {
90 return theAttributes.get(pName);
91 }
92
93
94
95
96
97
98 void storeAttribute(final ArduinoAttribute pAttr) throws ArduinoException {
99
100 if (theAttributes.containsKey(pAttr.getName())) {
101 throw new ArduinoException("Duplicate Attribute " + pAttr.getName());
102 }
103
104
105 theAttributes.put(pAttr.getName(), pAttr);
106 }
107
108
109
110
111
112
113
114
115 public static void parseAttributeDef(final ArduinoSystem pSystem,
116 final String pMarker,
117 final String pAttrDef) throws ArduinoException {
118
119 final String myMarker = ArduinoParser.nextToken(pAttrDef);
120 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
121 if (!myMarker.equals(pMarker)) {
122 throw new ArduinoException("Invalid AttrDef marker", pAttrDef);
123 }
124
125
126 final boolean isRelation = MARKER_REL_DEF.equals(pMarker);
127 final String myClassDef = ArduinoParser.nextToken(myDef);
128 final ArduinoAttrClass myClass = ArduinoAttrClass.parseAttrClass(myClassDef);
129 if (myClass.isRelation() != isRelation) {
130 throw new ArduinoException("Relation mismatch for AttrDef", pAttrDef);
131 }
132 if (myClass != ArduinoAttrClass.SYSTEM) {
133 myDef = ArduinoParser.stripToken(myDef, myClassDef);
134 }
135
136
137 try {
138
139 final String myName = ArduinoParser.nextQuotedToken(myDef);
140 myDef = ArduinoParser.stripQuotedToken(myDef, myName);
141
142
143 final int myLen = myDef.length();
144 if (myDef.length() == 0 || myDef.charAt(myLen - 1) != ArduinoChar.SEMICOLON) {
145 throw new ArduinoParserException("Missing AttrDef terminator", myDef);
146 }
147 myDef = myDef.substring(0, myLen - 1);
148
149
150 final String myTypeDef = ArduinoParser.nextToken(myDef);
151 final ArduinoAttrType myType = ArduinoAttrType.parseAttrType(myTypeDef);
152 myDef = ArduinoParser.stripToken(myDef, myTypeDef);
153
154
155 final ArduinoAttributenoAttribute.html#ArduinoAttribute">ArduinoAttribute myAttr = new ArduinoAttribute(myName, myClass, myType);
156 myAttr.setConstraints(ArduinoAttrConstraints.parseConstraints(myAttr, myDef));
157 pSystem.storeAttribute(myAttr);
158
159
160 } catch (ArduinoParserException e) {
161 throw new ArduinoException(e.getMessage() + ArduinoChar.COLON + e.getDetail(), pAttrDef);
162 }
163 }
164
165
166
167
168
169
170
171
172 public static void parseAttributeDefault(final ArduinoSystem pSystem,
173 final String pMarker,
174 final String pAttrDef) throws ArduinoException {
175
176 final String myMarker = ArduinoParser.nextToken(pAttrDef);
177 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
178 if (!myMarker.equals(pMarker)) {
179 throw new ArduinoException("Invalid AttrDefault marker", pAttrDef);
180 }
181
182
183 try {
184
185 final boolean isRelation = MARKER_REL_DEFAULT.equals(pMarker);
186 final String myName = ArduinoParser.nextQuotedToken(myDef);
187 myDef = ArduinoParser.stripQuotedToken(myDef, myName);
188
189
190 final int myLen = myDef.length();
191 if (myDef.length() == 0 || myDef.charAt(myLen - 1) != ArduinoChar.SEMICOLON) {
192 throw new ArduinoException("Missing AttrDefault terminator", pAttrDef);
193 }
194 myDef = myDef.substring(0, myLen - 1);
195
196
197 final ArduinoAttribute myAttr = pSystem.findAttributeByName(myName);
198 if (myAttr.getAttrClass().isRelation() != isRelation) {
199 throw new ArduinoException("Relation mismatch for AttrDefault", pAttrDef);
200 }
201 final Object myDefault = parseAttributeValue(myAttr, myDef);
202
203
204 myAttr.setDefault(myDefault);
205
206
207 } catch (ArduinoParserException e) {
208 throw new ArduinoException(e.getMessage() + ArduinoChar.COLON + e.getDetail(), pAttrDef);
209 }
210 }
211
212
213
214
215
216
217
218
219 private static Object parseAttributeValue(final ArduinoAttribute pAttr,
220 final String pValueDef) throws ArduinoParserException {
221
222 Object myValue;
223 switch (pAttr.getAttrType()) {
224 case FLOAT:
225 case INT:
226 case HEX:
227 myValue = ArduinoParser.parseNumber(pValueDef);
228 break;
229 case STRING:
230 myValue = ArduinoParser.nextQuotedToken(pValueDef);
231 break;
232 case ENUM:
233 default:
234 myValue = pValueDef.charAt(0) == ArduinoChar.QUOTE
235 ? ArduinoParser.nextQuotedToken(pValueDef)
236 : ArduinoParser.parseNumber(ArduinoParser.nextToken(pValueDef));
237 break;
238 }
239
240
241 final ArduinoAttrConstraints myConstraints = pAttr.getConstraints();
242 if (myConstraints != null) {
243
244 myValue = myConstraints.checkValue(myValue);
245 }
246
247
248 return myValue;
249 }
250
251
252
253
254
255
256
257
258 public static void parseAttribute(final ArduinoSystem pSystem,
259 final String pMarker,
260 final String pAttrDef) throws ArduinoException {
261
262 final String myMarker = ArduinoParser.nextToken(pAttrDef);
263 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
264 if (!myMarker.equals(pMarker)) {
265 throw new ArduinoException("Invalid Attr marker", pAttrDef);
266 }
267
268
269 try {
270
271 final boolean isRelation = MARKER_REL.equals(pMarker);
272 final String myName = ArduinoParser.nextQuotedToken(myDef);
273 myDef = ArduinoParser.stripQuotedToken(myDef, myName);
274
275
276 final int myLen = myDef.length();
277 if (myDef.length() == 0 || myDef.charAt(myLen - 1) != ArduinoChar.SEMICOLON) {
278 throw new ArduinoException("Missing Attr terminator", pAttrDef);
279 }
280 myDef = myDef.substring(0, myLen - 1);
281
282
283 final ArduinoAttribute myAttr = pSystem.findAttributeByName(myName);
284 if (myAttr.getAttrClass().isRelation() != isRelation) {
285 throw new ArduinoException("Relation mismatch for Attr", pAttrDef);
286 }
287
288
289 switch (myAttr.getAttrClass()) {
290 case NODE:
291 parseNodeAttribute(pSystem, myAttr, myDef);
292 break;
293 case MESSAGE:
294 parseMessageAttribute(pSystem, myAttr, myDef);
295 break;
296 case SIGNAL:
297 parseSignalAttribute(pSystem, myAttr, myDef);
298 break;
299 case NODE2MSG:
300 parseNode2MsgAttribute(pSystem, myAttr, myDef);
301 break;
302 case NODE2SIGNAL:
303 parseNode2SignalAttribute(pSystem, myAttr, myDef);
304 break;
305 case SYSTEM:
306 default:
307 parseSystemAttribute(pSystem, myAttr, myDef);
308 break;
309 }
310
311
312 } catch (ArduinoParserException e) {
313 throw new ArduinoException(e.getMessage() + ArduinoChar.COLON + e.getDetail(), pAttrDef);
314 }
315 }
316
317
318
319
320
321
322
323
324 private static void parseSystemAttribute(final ArduinoSystem pSystem,
325 final ArduinoAttribute pAttr,
326 final String pAttrDef) throws ArduinoParserException {
327
328 final Object myValue = parseAttributeValue(pAttr, pAttrDef);
329 pSystem.setAttrValue(pAttr, myValue);
330 }
331
332
333
334
335
336
337
338
339 private static void parseNodeAttribute(final ArduinoSystem pSystem,
340 final ArduinoAttribute pAttr,
341 final String pAttrDef) throws ArduinoParserException {
342
343 final String myMarker = ArduinoParser.nextToken(pAttrDef);
344 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
345 if (!myMarker.equals(ArduinoNode.MARKER)) {
346 throw new ArduinoParserException("Invalid Node marker", pAttrDef);
347 }
348
349
350 final String myName = ArduinoParser.nextToken(myDef);
351 myDef = ArduinoParser.stripToken(myDef, myName);
352
353
354 final ArduinoNode myNode = pSystem.findNodeByName(myName);
355 final Object myValue = parseAttributeValue(pAttr, myDef);
356 myNode.setAttrValue(pAttr, myValue);
357 }
358
359
360
361
362
363
364
365
366 private static void parseMessageAttribute(final ArduinoSystem pSystem,
367 final ArduinoAttribute pAttr,
368 final String pAttrDef) throws ArduinoParserException {
369
370 final String myMarker = ArduinoParser.nextToken(pAttrDef);
371 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
372 if (!myMarker.equals(ArduinoMessage.MARKER)) {
373 throw new ArduinoParserException("Invalid Message marker", pAttrDef);
374 }
375
376
377 final String myMsgId = ArduinoParser.nextToken(myDef);
378 myDef = ArduinoParser.stripToken(myDef, myMsgId);
379
380
381 final ArduinoMessage myMessage = pSystem.findMessageById(myMsgId);
382 final Object myValue = parseAttributeValue(pAttr, myDef);
383 myMessage.setAttrValue(pAttr, myValue);
384 }
385
386
387
388
389
390
391
392
393 private static void parseNode2MsgAttribute(final ArduinoSystem pSystem,
394 final ArduinoAttribute pAttr,
395 final String pAttrDef) throws ArduinoParserException {
396
397 String myMarker = ArduinoParser.nextToken(pAttrDef);
398 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
399 if (!myMarker.equals(ArduinoAttribute.NODE2MSG_MARKER)) {
400 throw new ArduinoParserException("Invalid Node2Message marker", pAttrDef);
401 }
402
403
404 final String myName = ArduinoParser.nextToken(myDef);
405 myDef = ArduinoParser.stripToken(myDef, myName);
406 final ArduinoNode myNode = pSystem.findNodeByName(myName);
407
408
409 myMarker = ArduinoParser.nextToken(myDef);
410 myDef = ArduinoParser.stripToken(myDef, myMarker);
411 if (!myMarker.equals(ArduinoMessage.MARKER)) {
412 throw new ArduinoParserException("Invalid Node2Msg message marker", pAttrDef);
413 }
414
415
416 final String myMsgId = ArduinoParser.nextToken(myDef);
417 myDef = ArduinoParser.stripToken(myDef, myMsgId);
418
419
420 final ArduinoMessage myMessage = pSystem.findMessageById(myMsgId);
421 final Object myValue = parseAttributeValue(pAttr, myDef);
422 if (!myNode.receivesMessage(myMessage)) {
423 throw new ArduinoParserException("Impossible Node2Msg relationship", pAttrDef);
424 }
425 myNode.setRelationValue(pAttr, myMessage, myValue);
426 }
427
428
429
430
431
432
433
434
435 private static void parseSignalAttribute(final ArduinoSystem pSystem,
436 final ArduinoAttribute pAttr,
437 final String pAttrDef) throws ArduinoParserException {
438
439 final String myMarker = ArduinoParser.nextToken(pAttrDef);
440 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
441 if (!myMarker.equals(ArduinoSignal.MARKER)) {
442 throw new ArduinoParserException("Invalid Signal marker", pAttrDef);
443 }
444
445
446 final String myMsgId = ArduinoParser.nextToken(myDef);
447 myDef = ArduinoParser.stripToken(myDef, myMsgId);
448
449
450 final String myName = ArduinoParser.nextToken(myDef);
451 myDef = ArduinoParser.stripToken(myDef, myName);
452
453
454 final ArduinoSignal mySignal = pSystem.findSignalByIdAndName(myMsgId, myName);
455 final Object myValue = parseAttributeValue(pAttr, myDef);
456 mySignal.setAttrValue(pAttr, myValue);
457 }
458
459
460
461
462
463
464
465
466 private static void parseNode2SignalAttribute(final ArduinoSystem pSystem,
467 final ArduinoAttribute pAttr,
468 final String pAttrDef) throws ArduinoParserException {
469
470 String myMarker = ArduinoParser.nextToken(pAttrDef);
471 String myDef = ArduinoParser.stripToken(pAttrDef, myMarker);
472 if (!myMarker.equals(ArduinoAttribute.NODE2SIG_MARKER)) {
473 throw new ArduinoParserException("Invalid Node2Signal marker", pAttrDef);
474 }
475
476
477 String myName = ArduinoParser.nextToken(myDef);
478 myDef = ArduinoParser.stripToken(myDef, myName);
479 final ArduinoNode myNode = pSystem.findNodeByName(myName);
480
481
482 myMarker = ArduinoParser.nextToken(myDef);
483 myDef = ArduinoParser.stripToken(myDef, myMarker);
484 if (!myMarker.equals(ArduinoSignal.MARKER)) {
485 throw new ArduinoParserException("Invalid Node2Signal signal marker", pAttrDef);
486 }
487
488
489 final String myMsgId = ArduinoParser.nextToken(myDef);
490 myDef = ArduinoParser.stripToken(myDef, myMsgId);
491
492
493 myName = ArduinoParser.nextToken(myDef);
494 myDef = ArduinoParser.stripToken(myDef, myName);
495
496
497 final ArduinoSignal mySignal = pSystem.findSignalByIdAndName(myMsgId, myName);
498 final Object myValue = parseAttributeValue(pAttr, myDef);
499 if (!myNode.receivesSignal(mySignal)) {
500 throw new ArduinoParserException("Impossible Node2Signal relationship", pAttrDef);
501 }
502 myNode.setRelationValue(pAttr, mySignal, myValue);
503 }
504 }