1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.prometheus.data;
18
19 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
20 import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
21 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem.MetisFieldDef;
22 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem.MetisFieldSetDef;
23 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem.MetisFieldVersionedDef;
24 import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionValues;
25 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
26 import io.github.tonywasher.joceanus.prometheus.data.PrometheusData.PrometheusDataItemCtl;
27 import io.github.tonywasher.joceanus.prometheus.data.PrometheusData.PrometheusDataValuesCtl;
28 import io.github.tonywasher.joceanus.prometheus.data.PrometheusData.PrometheusGroupedItemCtl;
29 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncrypted.PrometheusDataInfoItemCtl;
30 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncrypted.PrometheusDataInfoSetCtl;
31 import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncrypted.PrometheusDataInfoSetItemCtl;
32 import org.w3c.dom.Document;
33 import org.w3c.dom.Element;
34 import org.w3c.dom.Node;
35
36 import java.util.ArrayList;
37 import java.util.Iterator;
38 import java.util.LinkedHashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Map.Entry;
42
43
44
45
46
47
48 public class PrometheusDataValues
49 implements PrometheusDataValuesCtl {
50
51
52
53 private static final String TAG_INFOSET = PrometheusDataResource.DATAINFOSET_NAME.getValue();
54
55
56
57
58 private static final String TAG_CHILDREN = PrometheusDataResource.DATAVALUES_CHILDREN.getValue();
59
60
61
62
63 private static final String TAG_CHILD = PrometheusDataResource.DATAVALUES_CHILD.getValue();
64
65
66
67
68 protected static final String ATTR_TYPE = PrometheusDataResource.DATAVALUES_ATTRTYPE.getValue();
69
70
71
72
73 protected static final String ATTR_SIZE = PrometheusDataResource.DATAVALUES_ATTRSIZE.getValue();
74
75
76
77
78 protected static final String ATTR_VERS = PrometheusDataResource.DATAVALUES_ATTRVER.getValue();
79
80
81
82
83 private final String theItemType;
84
85
86
87
88 private final Map<MetisDataFieldId, Object> theFields;
89
90
91
92
93 private final List<PrometheusInfoItem> theInfoItems;
94
95
96
97
98 private final List<PrometheusDataValues> theChildren;
99
100
101
102
103
104
105
106 protected PrometheusDataValues(final PrometheusDataItem pItem,
107 final String pItemName) {
108
109 theItemType = pItemName;
110
111
112 theFields = new LinkedHashMap<>();
113
114
115 theFields.put(MetisDataResource.DATA_ID, pItem.getIndexedId());
116
117
118 final MetisFieldVersionValues myValues = pItem.getValues();
119
120
121 final Iterator<MetisFieldDef> myIterator = pItem.getDataFieldSet().fieldIterator();
122 while (myIterator.hasNext()) {
123 final MetisFieldDef myField = myIterator.next();
124 final MetisDataFieldId myFieldId = myField.getFieldId();
125
126
127 if (!(myField instanceof MetisFieldVersionedDef myVersioned)
128 || !myVersioned.isEquality()) {
129 continue;
130 }
131
132
133 if (pItem.includeXmlField(myFieldId)) {
134
135 theFields.put(myFieldId, myValues.getValue(myField));
136 }
137 }
138
139
140 if (pItem instanceof PrometheusDataInfoSetItemCtl myInfoItem) {
141
142 final PrometheusDataInfoSetCtl myInfoSet = myInfoItem.getInfoSet();
143
144
145 if (myInfoSet.isEmpty()) {
146
147 theInfoItems = null;
148 } else {
149
150 theInfoItems = new ArrayList<>();
151
152
153 final Iterator<?> myInfoIterator = myInfoSet.iterator();
154 while (myInfoIterator.hasNext()) {
155 final Object myCurr = myInfoIterator.next();
156
157
158 if (myCurr instanceof PrometheusDataInfoItemCtl myItem) {
159
160 final PrometheusInfoItem myInfo = new PrometheusInfoItem(myItem);
161 theInfoItems.add(myInfo);
162 }
163 }
164 }
165
166
167 } else {
168 theInfoItems = null;
169 }
170
171
172 if (pItem instanceof PrometheusGroupedItemCtl myGrouped) {
173
174 final Iterator<PrometheusDataItemCtl> myChildIterator = myGrouped.childIterator();
175
176
177 if (myChildIterator == null) {
178 theChildren = null;
179 } else {
180
181 theChildren = new ArrayList<>();
182
183
184 while (myChildIterator.hasNext()) {
185 final PrometheusDataItem myCurr = (PrometheusDataItem) myChildIterator.next();
186
187
188 final PrometheusDataValues myChild = new PrometheusDataValues(myCurr, TAG_CHILD);
189 theChildren.add(myChild);
190 }
191 }
192
193
194 } else {
195 theChildren = null;
196 }
197 }
198
199
200
201
202
203
204
205 private PrometheusDataValues(final PrometheusDataItem pOwner,
206 final PrometheusInfoItem pInfo) {
207
208 theItemType = "";
209
210
211 theFields = new LinkedHashMap<>();
212
213
214 final Integer myId = pInfo.getId();
215 if (myId != null) {
216 theFields.put(MetisDataResource.DATA_ID, myId);
217 }
218
219
220 theFields.put(PrometheusDataResource.DATAINFO_TYPE, pInfo.getName());
221
222
223 theFields.put(PrometheusDataResource.DATAINFO_OWNER, pOwner.getIndexedId());
224
225
226 theFields.put(PrometheusDataResource.DATAINFO_VALUE, pInfo.getValue());
227
228
229 theInfoItems = null;
230 theChildren = null;
231 }
232
233
234
235
236
237
238
239 public PrometheusDataValues(final Element pElement,
240 final MetisFieldSetDef pFields) {
241 this(pElement, pFields, pElement.getNodeName());
242 }
243
244
245
246
247
248
249
250
251 protected PrometheusDataValues(final Element pElement,
252 final MetisFieldSetDef pFields,
253 final String pItemName) {
254
255 theItemType = pItemName;
256
257
258 theFields = new LinkedHashMap<>();
259
260
261 final Integer myId = getId(pElement);
262 if (myId != null) {
263 theFields.put(MetisDataResource.DATA_ID, myId);
264 }
265
266
267 final Iterator<MetisFieldDef> myIterator = pFields.fieldIterator();
268 while (myIterator.hasNext()) {
269 final MetisFieldDef myField = myIterator.next();
270
271
272 if (myField instanceof MetisFieldVersionedDef myVersioned
273 && myVersioned.isEquality()) {
274
275 final Element myChild = getChild(pElement, myField.getFieldId().getId());
276 if (myChild != null) {
277
278 theFields.put(myField.getFieldId(), myChild.getTextContent());
279 }
280 }
281 }
282
283
284 final Element myInfoSet = getChild(pElement, TAG_INFOSET);
285 if (myInfoSet != null) {
286
287 theInfoItems = new ArrayList<>();
288
289
290 for (Node myCurr = myInfoSet.getFirstChild(); myCurr != null; myCurr = myCurr.getNextSibling()) {
291
292 if (myCurr instanceof Element myChild) {
293
294 final PrometheusInfoItem myInfo = new PrometheusInfoItem(myChild);
295 theInfoItems.add(myInfo);
296 }
297 }
298
299
300 } else {
301 theInfoItems = null;
302 }
303
304
305 final Element myChildren = getChild(pElement, TAG_CHILDREN);
306 if (myChildren != null) {
307
308 theChildren = new ArrayList<>();
309
310
311 for (Node myCurr = myChildren.getFirstChild(); myCurr != null; myCurr = myCurr.getNextSibling()) {
312
313 if (myCurr instanceof Element myChild
314 && TAG_CHILD.equals(myCurr.getNodeName())) {
315
316 final PrometheusDataValues myValues = new PrometheusDataValues(myChild, pFields, theItemType);
317 theChildren.add(myValues);
318 }
319 }
320
321
322 } else {
323 theChildren = null;
324 }
325 }
326
327
328
329
330
331
332 public PrometheusDataValues(final String pName) {
333
334 theItemType = pName;
335
336
337 theFields = new LinkedHashMap<>();
338
339
340 theInfoItems = null;
341 theChildren = null;
342 }
343
344
345
346
347
348
349 public PrometheusDataValues(final PrometheusDataItem pItem) {
350 this(pItem, pItem.getDataFieldSet().getName());
351 }
352
353
354
355
356
357
358 public final String getItemType() {
359 return theItemType;
360 }
361
362
363
364
365
366
367 public final Iterator<Entry<MetisDataFieldId, Object>> fieldIterator() {
368 return theFields.entrySet().iterator();
369 }
370
371
372
373
374
375
376 public final boolean hasInfoItems() {
377 return theInfoItems != null;
378 }
379
380
381
382
383
384
385 public final Iterator<PrometheusInfoItem> infoIterator() {
386 return theInfoItems.iterator();
387 }
388
389
390
391
392
393
394 public final boolean hasChildren() {
395 return theChildren != null;
396 }
397
398
399
400
401
402
403 public final Iterator<PrometheusDataValues> childIterator() {
404 return theChildren.iterator();
405 }
406
407
408
409
410
411
412
413 public void addValue(final MetisDataFieldId pField,
414 final Object pValue) {
415
416 if (pValue != null) {
417
418 theFields.put(pField, pValue);
419 }
420 }
421
422
423
424
425
426
427
428 public Object getValue(final MetisDataFieldId pField) {
429
430 return theFields.get(pField);
431 }
432
433
434
435
436
437
438
439
440
441 public <T> T getValue(final MetisDataFieldId pField,
442 final Class<T> pClass) {
443
444 return pClass.cast(getValue(pField));
445 }
446
447
448
449
450
451
452
453 private static Integer getId(final Element pElement) {
454
455 final String myId = pElement.getAttribute(MetisDataResource.DATA_ID.getId());
456 return !myId.isEmpty()
457 ? Integer.parseInt(myId)
458 : null;
459 }
460
461
462
463
464
465
466
467
468 private static Element getChild(final Element pParent,
469 final String pName) {
470
471 for (Node myCurr = pParent.getFirstChild(); myCurr != null; myCurr = myCurr.getNextSibling()) {
472
473 if (myCurr instanceof Element myElement
474 && pName.equals(myCurr.getNodeName())) {
475
476 return myElement;
477 }
478 }
479
480
481 return null;
482 }
483
484
485
486
487
488
489
490
491
492 protected Element createXML(final Document pDocument,
493 final OceanusDataFormatter pFormatter,
494 final boolean pStoreIds) {
495
496 final Element myElement = pDocument.createElement(theItemType);
497
498
499 for (Entry<MetisDataFieldId, Object> myEntry : theFields.entrySet()) {
500
501 final MetisDataFieldId myFieldId = myEntry.getKey();
502 final Object myValue = myEntry.getValue();
503
504
505 if (MetisDataResource.DATA_ID.equals(myFieldId)) {
506
507 if (pStoreIds) {
508 myElement.setAttribute(myFieldId.getId(), myValue.toString());
509 }
510
511
512 continue;
513 }
514
515
516 final Element myChild = pDocument.createElement(myFieldId.getId());
517 myElement.appendChild(myChild);
518
519
520 myChild.setTextContent(pFormatter.formatObject(myValue));
521 }
522
523
524 if (theInfoItems != null) {
525
526 final Element myInfoSet = pDocument.createElement(TAG_INFOSET);
527 myElement.appendChild(myInfoSet);
528
529
530 for (PrometheusInfoItem myInfo : theInfoItems) {
531
532 final Element myItem = pDocument.createElement(myInfo.getName());
533 myInfoSet.appendChild(myItem);
534
535
536 if (pStoreIds) {
537 myItem.setAttribute(MetisDataResource.DATA_ID.getValue(), myInfo.getId().toString());
538 }
539
540
541 myItem.setTextContent(pFormatter.formatObject(myInfo.getValue()));
542 }
543 }
544
545
546 if (theChildren != null) {
547
548 final Element myChildren = pDocument.createElement(TAG_CHILDREN);
549 myElement.appendChild(myChildren);
550
551
552 final Iterator<PrometheusDataValues> myIterator = theChildren.iterator();
553 while (myIterator.hasNext()) {
554 final PrometheusDataValues myValues = myIterator.next();
555
556
557 final Element myChild = myValues.createXML(pDocument, pFormatter, pStoreIds);
558 myChildren.appendChild(myChild);
559 }
560 }
561
562
563 return myElement;
564 }
565
566
567
568
569 public static final class PrometheusInfoItem {
570
571
572
573 private final String theName;
574
575
576
577
578 private final Integer theId;
579
580
581
582
583 private final Object theValue;
584
585
586
587
588
589
590 private PrometheusInfoItem(final PrometheusDataInfoItemCtl pInfo) {
591
592 final PrometheusDataInfoClass myClass = pInfo.getInfoClass();
593
594
595 theName = myClass.toString();
596 theId = pInfo.getIndexedId();
597 theValue = myClass.isLink()
598 ? pInfo.getLink()
599 : pInfo.getValue(Object.class);
600 }
601
602
603
604
605
606
607 private PrometheusInfoItem(final Element pElement) {
608
609 theName = pElement.getNodeName();
610 theId = PrometheusDataValues.getId(pElement);
611 theValue = pElement.getTextContent();
612 }
613
614
615
616
617
618
619 public String getName() {
620 return theName;
621 }
622
623
624
625
626
627
628 public Integer getId() {
629 return theId;
630 }
631
632
633
634
635
636
637 public Object getValue() {
638 return theValue;
639 }
640
641 @Override
642 public boolean equals(final Object pThat) {
643
644 if (this == pThat) {
645 return true;
646 }
647 if (pThat == null) {
648 return false;
649 }
650
651
652 if (pThat.getClass() != getClass()) {
653 return false;
654 }
655
656
657 final PrometheusInfoItem myItem = (PrometheusInfoItem) pThat;
658
659 if (!theName.equals(myItem.getName())) {
660 return false;
661 }
662 if (!theId.equals(myItem.getId())) {
663 return false;
664 }
665 return theValue.equals(myItem.getValue());
666 }
667
668 @Override
669 public int hashCode() {
670 return theName.hashCode() + theId + theValue.hashCode();
671 }
672
673 @Override
674 public String toString() {
675 return theName + "=" + theValue;
676 }
677
678
679
680
681
682
683
684 public PrometheusDataValues getValues(final PrometheusDataItem pOwner) {
685 return new PrometheusDataValues(pOwner, this);
686 }
687 }
688 }