node-opcua-address-space 2.77.0 → 2.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/source/continuation_points/continuation_point_manager.d.ts +59 -0
- package/dist/source/continuation_points/continuation_point_manager.js +6 -6
- package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.js +1 -0
- package/dist/source/index.js.map +1 -1
- package/dist/source/loader/ensure_datatype_extracted.js +25 -0
- package/dist/source/loader/ensure_datatype_extracted.js.map +1 -1
- package/dist/source/loader/generateAddressSpaceRaw.d.ts +2 -1
- package/dist/source/loader/generateAddressSpaceRaw.js +2 -2
- package/dist/source/loader/generateAddressSpaceRaw.js.map +1 -1
- package/dist/source/loader/load_nodeset2.d.ts +7 -3
- package/dist/source/loader/load_nodeset2.js +66 -31
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/xml_writer.d.ts +5 -0
- package/dist/src/base_node_private.js +5 -0
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/index_current.d.ts +2 -1
- package/dist/src/index_current.js +3 -2
- package/dist/src/index_current.js.map +1 -1
- package/dist/src/namespace_impl.d.ts +2 -0
- package/dist/src/namespace_impl.js +11 -1
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/namespace_private.d.ts +1 -0
- package/dist/src/namespace_private.js.map +1 -1
- package/dist/src/nodeid_manager.d.ts +1 -0
- package/dist/src/nodeid_manager.js +14 -2
- package/dist/src/nodeid_manager.js.map +1 -1
- package/dist/src/nodeset_tools/dump_to_bsd.d.ts +2 -0
- package/dist/src/nodeset_tools/dump_to_bsd.js +164 -0
- package/dist/src/nodeset_tools/dump_to_bsd.js.map +1 -0
- package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +9 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.js +182 -87
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/tool_isSupertypeOf.js +12 -2
- package/dist/src/tool_isSupertypeOf.js.map +1 -1
- package/dist/src/ua_data_type_impl.js +10 -5
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_object_impl.js +8 -1
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.js +4 -0
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.js +1 -1
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
- package/distHelpers/get_mini_address_space.js +1 -1
- package/distHelpers/get_mini_address_space.js.map +1 -1
- package/distNodeJS/generate_address_space.d.ts +3 -1
- package/distNodeJS/generate_address_space.js +13 -2
- package/distNodeJS/generate_address_space.js.map +1 -1
- package/package.json +22 -22
- package/source/continuation_points/continuation_point_manager.ts +13 -12
- package/source/index.ts +1 -0
- package/source/loader/ensure_datatype_extracted.ts +38 -3
- package/source/loader/generateAddressSpaceRaw.ts +4 -3
- package/source/loader/load_nodeset2.ts +86 -33
- package/source/xml_writer.ts +3 -0
- package/source_nodejs/generate_address_space.ts +27 -5
- package/src/base_node_private.ts +6 -0
- package/src/index_current.ts +3 -1
- package/src/namespace_impl.ts +24 -1
- package/src/namespace_private.ts +2 -0
- package/src/nodeid_manager.ts +14 -5
- package/src/nodeset_tools/{typedictionary_to_xml.ts → dump_to_bsd.ts} +24 -14
- package/src/nodeset_tools/nodeset_to_xml.ts +231 -74
- package/src/tool_isSupertypeOf.ts +14 -2
- package/src/ua_data_type_impl.ts +11 -7
- package/src/ua_object_impl.ts +12 -2
- package/src/ua_variable_impl.ts +6 -0
- package/src/ua_variable_impl_ext_obj.ts +1 -1
- package/test_helpers/get_mini_address_space.ts +1 -1
- package/test_helpers/test_fixtures/mini.Node.Set2.xml +29 -0
- package/test_helpers/test_fixtures/nodeset_no_aliases.xml +30 -0
- package/test_helpers/test_fixtures/nodeset_no_aliases_with_aliases.xml +31 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/* eslint-disable complexity */
|
|
1
2
|
/**
|
|
2
3
|
* @module node-opcua-address-space
|
|
3
4
|
*/
|
|
4
5
|
// produce nodeset xml files
|
|
5
6
|
import { assert } from "node-opcua-assert";
|
|
7
|
+
import { ObjectIds } from "node-opcua-constants";
|
|
6
8
|
import { make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
7
9
|
import { ExtensionObject } from "node-opcua-extension-object";
|
|
8
10
|
import {
|
|
@@ -29,7 +31,7 @@ import {
|
|
|
29
31
|
UAVariable,
|
|
30
32
|
UAVariableType
|
|
31
33
|
} from "node-opcua-address-space-base";
|
|
32
|
-
import { Int64, minOPCUADate, StatusCode } from "node-opcua-basic-types";
|
|
34
|
+
import { AttributeIds, Int64, minOPCUADate, StatusCode, StatusCodes } from "node-opcua-basic-types";
|
|
33
35
|
import { BrowseDescription, EnumDefinition, StructureDefinition, StructureType } from "node-opcua-types";
|
|
34
36
|
|
|
35
37
|
import { XmlWriter } from "../../source/xml_writer";
|
|
@@ -44,6 +46,7 @@ import { NamespaceImpl } from "../namespace_impl";
|
|
|
44
46
|
import { UAMethodImpl } from "../ua_method_impl";
|
|
45
47
|
import { UADataTypeImpl } from "../ua_data_type_impl";
|
|
46
48
|
import { UAVariableTypeImpl } from "../ua_variable_type_impl";
|
|
49
|
+
import { SessionContext } from "../index_current";
|
|
47
50
|
|
|
48
51
|
import { DefinitionMap2, TypeInfo } from "../../source/loader/make_xml_extension_object_parser";
|
|
49
52
|
import { makeDefinitionMap } from "../../source/loader/decode_xml_extension_object";
|
|
@@ -95,6 +98,12 @@ function b(xw: XmlWriter, browseName: QualifiedName): string {
|
|
|
95
98
|
return translateBrowseName(xw, browseName).toString().replace("ns=0;", "");
|
|
96
99
|
}
|
|
97
100
|
|
|
101
|
+
function _dumpReverseReferences(xw: XmlWriter, node: BaseNode) {
|
|
102
|
+
|
|
103
|
+
const addressSpace = node.addressSpace;
|
|
104
|
+
const hasSubtypeReferenceType = addressSpace.findReferenceType("HasSubtype")!;
|
|
105
|
+
|
|
106
|
+
}
|
|
98
107
|
function _dumpReferences(xw: XmlWriter, node: BaseNode) {
|
|
99
108
|
xw.startElement("References");
|
|
100
109
|
|
|
@@ -207,9 +216,53 @@ function _dumpXmlElement(xw: XmlWriter, v: string) {
|
|
|
207
216
|
</uax:Body>
|
|
208
217
|
</uax:ExtensionObject>
|
|
209
218
|
*/
|
|
219
|
+
type XmlNamespaceUri = string;
|
|
220
|
+
type XmlNs = string;
|
|
221
|
+
interface XmlWriterEx extends XmlWriter {
|
|
222
|
+
map: Record<XmlNamespaceUri, XmlNs>;
|
|
223
|
+
stackMap: Record<XmlNamespaceUri, XmlNs>[];
|
|
224
|
+
}
|
|
225
|
+
function initXmlWriterEx(xw: XmlWriter, map: Record<XmlNamespaceUri, XmlNs>): void {
|
|
226
|
+
const xwe = xw as XmlWriterEx;
|
|
227
|
+
xwe.map = map;
|
|
228
|
+
xwe.stackMap = [];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function getPrefix(xw: XmlWriter, namespace: XmlNamespaceUri): XmlNs {
|
|
232
|
+
const xwe = xw as XmlWriterEx;
|
|
233
|
+
if (!xwe.map) return "";
|
|
234
|
+
const p = xwe.map[namespace] || "";
|
|
235
|
+
return p ? p + ":" : "";
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function restoreDefaultNamespace(xw: XmlWriter) {
|
|
239
|
+
const xwe = xw as XmlWriterEx;
|
|
240
|
+
if (!xwe.map) return;
|
|
241
|
+
xwe.map = xwe.stackMap.pop()!;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function setDefaultNamespace(xw: XmlWriter, namespace: XmlNamespaceUri): void {
|
|
245
|
+
const xwe = xw as XmlWriterEx;
|
|
246
|
+
if (!xwe.map) return;
|
|
247
|
+
if (xwe.map[namespace] !== "") {
|
|
248
|
+
xw.writeAttribute("xmlns", namespace);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
xwe.stackMap.push({
|
|
252
|
+
...xwe.map
|
|
253
|
+
});
|
|
254
|
+
xwe.map[namespace] = "";
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function startElementEx(xw: XmlWriter, ns: XmlNs, name: string, defaultNamespace: XmlNamespaceUri) {
|
|
258
|
+
const xwe = xw as XmlWriterEx;
|
|
259
|
+
xw.startElement(name);
|
|
260
|
+
setDefaultNamespace(xw, defaultNamespace);
|
|
261
|
+
}
|
|
210
262
|
|
|
211
263
|
function _dumpNodeId(xw: XmlWriter, v: NodeId) {
|
|
212
|
-
xw.
|
|
264
|
+
const xmlns = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
265
|
+
xw.startElement(`${xmlns}Identifier`);
|
|
213
266
|
xw.text(n(xw, v));
|
|
214
267
|
xw.endElement();
|
|
215
268
|
}
|
|
@@ -224,7 +277,8 @@ function _dumpVariantValue(xw: XmlWriter, dataType: DataType, node: UAVariable |
|
|
|
224
277
|
if (dataType === DataType.Null) {
|
|
225
278
|
return;
|
|
226
279
|
}
|
|
227
|
-
xw.
|
|
280
|
+
const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
281
|
+
xw.startElement(`${uax}${DataType[dataType]}`);
|
|
228
282
|
const definitionMap = makeDefinitionMap(node.addressSpace);
|
|
229
283
|
_dumpVariantInnerValue(xw, dataType, dataTypeNode.nodeId, definitionMap, value);
|
|
230
284
|
xw.endElement();
|
|
@@ -306,6 +360,7 @@ function _dumpVariantInnerValue(
|
|
|
306
360
|
definitionMap: DefinitionMap2,
|
|
307
361
|
value: any
|
|
308
362
|
): void {
|
|
363
|
+
const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
309
364
|
switch (dataType) {
|
|
310
365
|
case null:
|
|
311
366
|
case DataType.Null:
|
|
@@ -347,12 +402,12 @@ function _dumpVariantInnerValue(
|
|
|
347
402
|
case DataType.Guid:
|
|
348
403
|
/*
|
|
349
404
|
<uax:Guid>
|
|
350
|
-
|
|
405
|
+
<uax:String>947c29a7-490d-4dc9-adda-1109e3e8fcb7</uax:String>
|
|
351
406
|
</uax:Guid>
|
|
352
407
|
*/
|
|
353
408
|
if (value !== undefined && value !== null) {
|
|
354
409
|
// xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
355
|
-
xw.startElement(
|
|
410
|
+
xw.startElement(`${uax}String`);
|
|
356
411
|
xw.text(value.toString());
|
|
357
412
|
xw.endElement();
|
|
358
413
|
}
|
|
@@ -406,24 +461,31 @@ function _dumpVariantExtensionObjectValue(
|
|
|
406
461
|
// const encodingDefaultXml = (getStructureTypeConstructor(schema.name) as any).encodingDefaultXml;
|
|
407
462
|
const encodingDefaultXml = value.schema.encodingDefaultXml;
|
|
408
463
|
if (!encodingDefaultXml) {
|
|
464
|
+
warningLog("dataType Name ", name, "with ", dataTypeNodeId.toString(), " does not have xml encoding");
|
|
409
465
|
// throw new Error("Extension Object doesn't provide a XML ");
|
|
410
466
|
return;
|
|
411
467
|
}
|
|
412
|
-
xw.
|
|
468
|
+
const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
469
|
+
startElementEx(xw, uax, `ExtensionObject`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
413
470
|
{
|
|
414
|
-
xw.
|
|
471
|
+
const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
472
|
+
xw.startElement(`${uax}TypeId`);
|
|
415
473
|
{
|
|
416
474
|
// find HasEncoding node
|
|
417
475
|
// xx var encodingDefaultXml = schema.encodingDefaultXml;
|
|
418
|
-
xw.startElement(
|
|
476
|
+
xw.startElement(`${uax}Identifier`);
|
|
419
477
|
xw.text(n(xw, encodingDefaultXml));
|
|
420
478
|
xw.endElement();
|
|
421
479
|
}
|
|
422
480
|
xw.endElement();
|
|
423
|
-
xw
|
|
481
|
+
startElementEx(xw, uax, "Body", "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
482
|
+
|
|
424
483
|
_dumpVariantExtensionObjectValue_Body(xw, definitionMap, name, definition as StructureDefinition, value);
|
|
484
|
+
|
|
485
|
+
restoreDefaultNamespace(xw);
|
|
425
486
|
xw.endElement();
|
|
426
487
|
}
|
|
488
|
+
restoreDefaultNamespace(xw);
|
|
427
489
|
xw.endElement();
|
|
428
490
|
}
|
|
429
491
|
|
|
@@ -454,10 +516,7 @@ function _isDefaultValue(value: Variant): boolean {
|
|
|
454
516
|
}
|
|
455
517
|
break;
|
|
456
518
|
case DataType.Boolean:
|
|
457
|
-
|
|
458
|
-
return true;
|
|
459
|
-
}
|
|
460
|
-
break;
|
|
519
|
+
return false; // we want it all the time !
|
|
461
520
|
case DataType.SByte:
|
|
462
521
|
case DataType.Byte:
|
|
463
522
|
case DataType.UInt16:
|
|
@@ -512,7 +571,7 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
|
|
|
512
571
|
}
|
|
513
572
|
assert(value instanceof Variant);
|
|
514
573
|
|
|
515
|
-
const dataTypeNode = addressSpace.
|
|
574
|
+
const dataTypeNode = addressSpace.findDataType(node.dataType);
|
|
516
575
|
if (!dataTypeNode) {
|
|
517
576
|
console.log("Cannot find dataType:", node.dataType);
|
|
518
577
|
return;
|
|
@@ -533,17 +592,14 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
|
|
|
533
592
|
}
|
|
534
593
|
xw.startElement("Value");
|
|
535
594
|
|
|
595
|
+
const uax = getPrefix(xw, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
536
596
|
if (isExtensionObject) {
|
|
537
|
-
const dataTypeNode = addressSpace.findDataType(node.dataType);
|
|
538
|
-
if (!dataTypeNode) {
|
|
539
|
-
throw new Error("Cannot find data type " + node.dataType.toString());
|
|
540
|
-
}
|
|
541
|
-
|
|
542
597
|
const encodeXml = _dumpVariantExtensionObjectValue2.bind(null, xw, dataTypeNode);
|
|
543
598
|
|
|
544
599
|
if (value.arrayType === VariantArrayType.Array) {
|
|
545
|
-
xw
|
|
600
|
+
startElementEx(xw, uax, `ListOf${baseDataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
546
601
|
value.value.forEach(encodeXml);
|
|
602
|
+
restoreDefaultNamespace(xw);
|
|
547
603
|
xw.endElement();
|
|
548
604
|
} else if (value.arrayType === VariantArrayType.Scalar) {
|
|
549
605
|
encodeXml(value.value);
|
|
@@ -556,14 +612,14 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
|
|
|
556
612
|
const encodeXml = _dumpVariantValue.bind(null, xw, value.dataType, node);
|
|
557
613
|
if (value.arrayType === VariantArrayType.Matrix) {
|
|
558
614
|
// console.log("Warning _dumpValue : Matrix not supported yet");
|
|
559
|
-
xw
|
|
560
|
-
xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
615
|
+
startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
561
616
|
value.value.forEach(encodeXml);
|
|
617
|
+
restoreDefaultNamespace(xw);
|
|
562
618
|
xw.endElement();
|
|
563
619
|
} else if (value.arrayType === VariantArrayType.Array) {
|
|
564
|
-
xw
|
|
565
|
-
xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
620
|
+
startElementEx(xw, uax, `ListOf${dataTypeName}`, "http://opcfoundation.org/UA/2008/02/Types.xsd");
|
|
566
621
|
value.value.forEach(encodeXml);
|
|
622
|
+
restoreDefaultNamespace(xw);
|
|
567
623
|
xw.endElement();
|
|
568
624
|
} else if (value.arrayType === VariantArrayType.Scalar) {
|
|
569
625
|
encodeXml(value.value);
|
|
@@ -586,12 +642,10 @@ function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAV
|
|
|
586
642
|
}
|
|
587
643
|
}
|
|
588
644
|
|
|
589
|
-
function visitUANode(node: BaseNode,
|
|
645
|
+
function visitUANode(node: BaseNode, data: DumpData, forward: boolean) {
|
|
590
646
|
assert(typeof forward === "boolean");
|
|
591
647
|
|
|
592
648
|
const addressSpace = node.addressSpace;
|
|
593
|
-
options.elements = options.elements || [];
|
|
594
|
-
options.index_el = options.index_el || {};
|
|
595
649
|
|
|
596
650
|
// visit references
|
|
597
651
|
function process_reference(reference: UAReference) {
|
|
@@ -604,18 +658,18 @@ function visitUANode(node: BaseNode, options: any, forward: boolean) {
|
|
|
604
658
|
return; // skip OPCUA namespace
|
|
605
659
|
}
|
|
606
660
|
const k = _hash(reference);
|
|
607
|
-
if (!
|
|
608
|
-
|
|
661
|
+
if (!data.index_el[k]) {
|
|
662
|
+
data.index_el[k] = 1;
|
|
609
663
|
|
|
610
664
|
const o = addressSpace.findNode(k)! as BaseNode;
|
|
611
665
|
if (o) {
|
|
612
|
-
visitUANode(o,
|
|
666
|
+
visitUANode(o, data, forward);
|
|
613
667
|
}
|
|
614
668
|
}
|
|
615
669
|
}
|
|
616
670
|
|
|
617
671
|
(node as BaseNodeImpl).ownReferences().forEach(process_reference);
|
|
618
|
-
|
|
672
|
+
data.elements.push(node as BaseNodeImpl);
|
|
619
673
|
return node;
|
|
620
674
|
}
|
|
621
675
|
|
|
@@ -682,11 +736,22 @@ function dumpReferencedNodes(xw: XmlWriter, node: BaseNode, forward: boolean) {
|
|
|
682
736
|
}
|
|
683
737
|
}
|
|
684
738
|
|
|
739
|
+
function getParent(node: BaseNode): BaseNode | null {
|
|
740
|
+
if (node instanceof UAVariableImpl || node instanceof UAMethodImpl || node instanceof UAObjectImpl) {
|
|
741
|
+
return node.parent;
|
|
742
|
+
}
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
745
|
+
|
|
685
746
|
const currentReadFlag = makeAccessLevelFlag("CurrentRead");
|
|
686
747
|
function dumpCommonAttributes(xw: XmlWriter, node: BaseNode) {
|
|
687
748
|
xw.writeAttribute("NodeId", n(xw, node.nodeId));
|
|
688
749
|
xw.writeAttribute("BrowseName", b(xw, node.browseName));
|
|
689
750
|
|
|
751
|
+
const parentNode = getParent(node);
|
|
752
|
+
if (parentNode) {
|
|
753
|
+
xw.writeAttribute("ParentNodeId", n(xw, parentNode.nodeId));
|
|
754
|
+
}
|
|
690
755
|
if (Object.prototype.hasOwnProperty.call(node, "symbolicName")) {
|
|
691
756
|
xw.writeAttribute("SymbolicName", (node as any).symbolicName);
|
|
692
757
|
}
|
|
@@ -779,13 +844,20 @@ function _dumpStructureDefinition(
|
|
|
779
844
|
}
|
|
780
845
|
}
|
|
781
846
|
|
|
847
|
+
function _dumpEncoding(xw: XmlWriter, uaEncoding: UAObject) {
|
|
848
|
+
const uaDescription = uaEncoding.findReferencesAsObject("HasDescription")[0];
|
|
849
|
+
if (uaDescription) {
|
|
850
|
+
dumpUAVariable(xw, uaDescription as UAVariable);
|
|
851
|
+
}
|
|
852
|
+
_dumpUAObject(xw, uaEncoding);
|
|
853
|
+
}
|
|
782
854
|
function _dumpEncodings(xw: XmlWriter, uaDataType: UADataType) {
|
|
783
855
|
const encodings = uaDataType.findReferencesExAsObject("HasEncoding", BrowseDirection.Forward);
|
|
784
|
-
for (const
|
|
785
|
-
if (
|
|
856
|
+
for (const uaEncoding of encodings) {
|
|
857
|
+
if (uaEncoding.nodeClass !== NodeClass.Object) {
|
|
786
858
|
continue;
|
|
787
859
|
}
|
|
788
|
-
|
|
860
|
+
_dumpEncoding(xw, uaEncoding as UAObject);
|
|
789
861
|
}
|
|
790
862
|
}
|
|
791
863
|
function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
|
|
@@ -798,16 +870,24 @@ function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
|
|
|
798
870
|
xw.endElement();
|
|
799
871
|
return;
|
|
800
872
|
}
|
|
873
|
+
|
|
801
874
|
if (uaDataType.isStructure()) {
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
875
|
+
// in case the namespace is conforming to 1.03 specification the DataTypeDefinition attribute
|
|
876
|
+
// will be not be readable....
|
|
877
|
+
|
|
878
|
+
const dataValue = uaDataType.readAttribute(SessionContext.defaultContext, AttributeIds.DataTypeDefinition);
|
|
879
|
+
|
|
880
|
+
if (dataValue.statusCode === StatusCodes.Good) {
|
|
881
|
+
const definition = uaDataType.getStructureDefinition();
|
|
882
|
+
const baseDefinition = uaDataTypeBase ? uaDataTypeBase.getStructureDefinition() : null;
|
|
883
|
+
xw.startElement("Definition");
|
|
884
|
+
xw.writeAttribute("Name", b(xw, uaDataType.browseName));
|
|
885
|
+
if (definition.structureType === StructureType.Union) {
|
|
886
|
+
xw.writeAttribute("IsUnion", "true");
|
|
887
|
+
}
|
|
888
|
+
_dumpStructureDefinition(xw, definition, baseDefinition);
|
|
889
|
+
xw.endElement();
|
|
808
890
|
}
|
|
809
|
-
_dumpStructureDefinition(xw, definition, baseDefinition);
|
|
810
|
-
xw.endElement();
|
|
811
891
|
return;
|
|
812
892
|
}
|
|
813
893
|
}
|
|
@@ -845,6 +925,10 @@ function _markAsVisited(xw: XmlWriter, node: BaseNode) {
|
|
|
845
925
|
}
|
|
846
926
|
|
|
847
927
|
function dumpUAVariable(xw: XmlWriter, node: UAVariable) {
|
|
928
|
+
assert(node.nodeClass === NodeClass.Variable);
|
|
929
|
+
if (xw.visitedNode[_hash(node)]) {
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
848
932
|
_markAsVisited(xw, node);
|
|
849
933
|
|
|
850
934
|
dumpReferencedNodes(xw, node, false);
|
|
@@ -886,6 +970,7 @@ function dumpUAVariable(xw: XmlWriter, node: UAVariable) {
|
|
|
886
970
|
}
|
|
887
971
|
|
|
888
972
|
function dumpUAVariableType(xw: XmlWriter, node: UAVariableType) {
|
|
973
|
+
assert(node.nodeClass === NodeClass.VariableType);
|
|
889
974
|
xw.visitedNode = xw.visitedNode || {};
|
|
890
975
|
assert(!xw.visitedNode[_hash(node)]);
|
|
891
976
|
xw.visitedNode[_hash(node)] = 1;
|
|
@@ -942,6 +1027,7 @@ function dumpUAObject(xw: XmlWriter, node: UAObject) {
|
|
|
942
1027
|
xw.writeComment("Object - " + b(xw, node.browseName) + " }}}} ");
|
|
943
1028
|
}
|
|
944
1029
|
function _dumpUAObject(xw: XmlWriter, node: UAObject) {
|
|
1030
|
+
assert(node.nodeClass === NodeClass.Object);
|
|
945
1031
|
xw.visitedNode = xw.visitedNode || {};
|
|
946
1032
|
assert(!xw.visitedNode[_hash(node)]);
|
|
947
1033
|
xw.visitedNode[_hash(node)] = 1;
|
|
@@ -994,6 +1080,7 @@ function dumpAggregates(xw: XmlWriter, node: BaseNode) {
|
|
|
994
1080
|
}
|
|
995
1081
|
|
|
996
1082
|
function dumpUAObjectType(xw: XmlWriter, node: UAObjectTypeImpl) {
|
|
1083
|
+
assert(node.nodeClass === NodeClass.ObjectType);
|
|
997
1084
|
assert(node instanceof UAObjectTypeImpl);
|
|
998
1085
|
xw.writeComment("ObjectType - " + b(xw, node.browseName) + " {{{{ ");
|
|
999
1086
|
_markAsVisited(xw, node);
|
|
@@ -1012,6 +1099,7 @@ function dumpUAObjectType(xw: XmlWriter, node: UAObjectTypeImpl) {
|
|
|
1012
1099
|
}
|
|
1013
1100
|
|
|
1014
1101
|
function dumpUAMethod(xw: XmlWriter, node: UAMethod) {
|
|
1102
|
+
assert(node.nodeClass === NodeClass.Method);
|
|
1015
1103
|
_markAsVisited(xw, node);
|
|
1016
1104
|
|
|
1017
1105
|
dumpReferencedNodes(xw, node, false);
|
|
@@ -1043,18 +1131,17 @@ function resolveDataTypeName(addressSpace: IAddressSpace, dataType: string | Nod
|
|
|
1043
1131
|
return dataTypeNode.browseName;
|
|
1044
1132
|
}
|
|
1045
1133
|
|
|
1046
|
-
function buildUpAliases(node: BaseNode, xw: XmlWriter,
|
|
1134
|
+
function buildUpAliases(node: BaseNode, xw: XmlWriter, data: BuildAliasesData) {
|
|
1047
1135
|
const addressSpace = node.addressSpace;
|
|
1048
1136
|
|
|
1049
|
-
|
|
1050
|
-
options.aliases_visited = options.aliases_visited || {};
|
|
1137
|
+
if (!data.aliases_visited) data.aliases_visited = {};
|
|
1051
1138
|
|
|
1052
1139
|
const k = _hash(node);
|
|
1053
1140
|
// istanbul ignore next
|
|
1054
|
-
if (
|
|
1141
|
+
if (data.aliases_visited[k]) {
|
|
1055
1142
|
return;
|
|
1056
1143
|
}
|
|
1057
|
-
|
|
1144
|
+
data.aliases_visited[k] = 1;
|
|
1058
1145
|
|
|
1059
1146
|
// put datatype into aliases list
|
|
1060
1147
|
if (node.nodeClass === NodeClass.Variable || node.nodeClass === NodeClass.VariableType) {
|
|
@@ -1064,8 +1151,8 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
|
|
|
1064
1151
|
// name
|
|
1065
1152
|
const dataTypeName = b(xw, resolveDataTypeName(addressSpace, nodeV.dataType));
|
|
1066
1153
|
if (dataTypeName) {
|
|
1067
|
-
if (!
|
|
1068
|
-
|
|
1154
|
+
if (!data.aliases[dataTypeName]) {
|
|
1155
|
+
data.aliases[dataTypeName] = n(xw, nodeV.dataType);
|
|
1069
1156
|
}
|
|
1070
1157
|
}
|
|
1071
1158
|
}
|
|
@@ -1074,8 +1161,8 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
|
|
|
1074
1161
|
// name
|
|
1075
1162
|
const dataTypeName = b(xw, resolveDataTypeName(addressSpace, nodeV.dataType));
|
|
1076
1163
|
if (dataTypeName) {
|
|
1077
|
-
if (!
|
|
1078
|
-
|
|
1164
|
+
if (!data.aliases[dataTypeName]) {
|
|
1165
|
+
data.aliases[dataTypeName] = n(xw, nodeV.dataType);
|
|
1079
1166
|
}
|
|
1080
1167
|
}
|
|
1081
1168
|
}
|
|
@@ -1084,11 +1171,11 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
|
|
|
1084
1171
|
function collectReferenceNameInAlias(reference: UAReference) {
|
|
1085
1172
|
// reference.referenceType
|
|
1086
1173
|
const key = b(xw, getReferenceType(reference).browseName);
|
|
1087
|
-
if (!
|
|
1174
|
+
if (!data.aliases.key) {
|
|
1088
1175
|
if (reference.referenceType.namespace === 0) {
|
|
1089
|
-
|
|
1176
|
+
data.aliases[key] = reference.referenceType.toString().replace("ns=0;", "");
|
|
1090
1177
|
} else {
|
|
1091
|
-
|
|
1178
|
+
data.aliases[key] = n(xw, reference.referenceType);
|
|
1092
1179
|
}
|
|
1093
1180
|
}
|
|
1094
1181
|
}
|
|
@@ -1096,7 +1183,7 @@ function buildUpAliases(node: BaseNode, xw: XmlWriter, options: any) {
|
|
|
1096
1183
|
node.allReferences().forEach(collectReferenceNameInAlias);
|
|
1097
1184
|
}
|
|
1098
1185
|
|
|
1099
|
-
function writeAliases(xw: XmlWriter, aliases:
|
|
1186
|
+
function writeAliases(xw: XmlWriter, aliases: Record<string, NodeIdString>) {
|
|
1100
1187
|
xw.startElement("Aliases");
|
|
1101
1188
|
|
|
1102
1189
|
if (aliases) {
|
|
@@ -1154,11 +1241,29 @@ function sortByNodeId(a: { nodeId: NodeId }, b: { nodeId: NodeId }) {
|
|
|
1154
1241
|
return a.nodeId.toString() < b.nodeId.toString() ? -1 : 1;
|
|
1155
1242
|
}
|
|
1156
1243
|
|
|
1157
|
-
|
|
1244
|
+
interface Dumpable {
|
|
1245
|
+
dumpXML(xw: typeof XMLWriter): void;
|
|
1246
|
+
}
|
|
1247
|
+
type NodeIdString = string;
|
|
1248
|
+
|
|
1249
|
+
export interface BuildAliasesData {
|
|
1250
|
+
aliases: Record<string, NodeIdString>;
|
|
1251
|
+
aliases_visited?: Record<string, unknown>;
|
|
1252
|
+
}
|
|
1253
|
+
interface DumpData extends BuildAliasesData {
|
|
1254
|
+
elements: Dumpable[];
|
|
1255
|
+
index_el: Record<string, number>;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
export interface DumpXMLOptions {
|
|
1259
|
+
/** */
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
export function dumpXml(node: BaseNode, options: DumpXMLOptions): void {
|
|
1158
1263
|
const namespace = node.namespace as NamespacePrivate;
|
|
1159
1264
|
|
|
1160
1265
|
// make a first visit so that we determine which node to output and in which order
|
|
1161
|
-
const
|
|
1266
|
+
const data: DumpData = { aliases: {}, aliases_visited: {}, index_el: {}, elements: [] };
|
|
1162
1267
|
|
|
1163
1268
|
const dependency = constructNamespaceDependency(namespace);
|
|
1164
1269
|
const translationTable = constructNamespaceTranslationTable(dependency);
|
|
@@ -1166,7 +1271,7 @@ export function dumpXml(node: BaseNode, options: any): void {
|
|
|
1166
1271
|
const xw = new XMLWriter(true);
|
|
1167
1272
|
xw.translationTable = translationTable;
|
|
1168
1273
|
|
|
1169
|
-
visitUANode(node,
|
|
1274
|
+
visitUANode(node, data, false);
|
|
1170
1275
|
|
|
1171
1276
|
xw.startDocument({ encoding: "utf-8" });
|
|
1172
1277
|
xw.startElement("UANodeSet");
|
|
@@ -1176,10 +1281,26 @@ export function dumpXml(node: BaseNode, options: any): void {
|
|
|
1176
1281
|
xw.writeAttribute("LastModified", new Date().toISOString());
|
|
1177
1282
|
xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd");
|
|
1178
1283
|
|
|
1179
|
-
buildUpAliases(node, xw,
|
|
1180
|
-
writeAliases(xw,
|
|
1284
|
+
buildUpAliases(node, xw, data);
|
|
1285
|
+
writeAliases(xw, data.aliases);
|
|
1286
|
+
|
|
1287
|
+
const xmlNamspace = {
|
|
1288
|
+
default: { namespace: "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" }
|
|
1289
|
+
};
|
|
1181
1290
|
|
|
1182
|
-
|
|
1291
|
+
xw.startElement("Extensions");
|
|
1292
|
+
{
|
|
1293
|
+
xw.startElement("Extension");
|
|
1294
|
+
{
|
|
1295
|
+
xw.startElement("ModelInfo");
|
|
1296
|
+
xw.writeAttribute("NodeOPCUA");
|
|
1297
|
+
xw.endElement();
|
|
1298
|
+
}
|
|
1299
|
+
xw.endElement();
|
|
1300
|
+
}
|
|
1301
|
+
xw.endElement();
|
|
1302
|
+
|
|
1303
|
+
for (const el of data.elements!) {
|
|
1183
1304
|
el.dumpXML(xw);
|
|
1184
1305
|
}
|
|
1185
1306
|
|
|
@@ -1231,6 +1352,12 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
|
|
|
1231
1352
|
// ------------- INamespace Uris
|
|
1232
1353
|
xw.startElement("NamespaceUris");
|
|
1233
1354
|
|
|
1355
|
+
initXmlWriterEx(xw, {
|
|
1356
|
+
"http://opcfoundation.org/UA/2011/03/UANodeSet.xsd": "",
|
|
1357
|
+
"http://opcfoundation.org/UA/2008/02/Types.xsd": "uax",
|
|
1358
|
+
"http://www.w3.org/2001/XMLSchema-instance": "xsi"
|
|
1359
|
+
});
|
|
1360
|
+
|
|
1234
1361
|
// xx const namespaceArray = namespace.addressSpace.getNamespaceArray();
|
|
1235
1362
|
for (const depend of dependency) {
|
|
1236
1363
|
if (depend.index === 0) {
|
|
@@ -1264,11 +1391,11 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
|
|
|
1264
1391
|
}
|
|
1265
1392
|
xw.endElement();
|
|
1266
1393
|
|
|
1267
|
-
const
|
|
1394
|
+
const data: BuildAliasesData = { aliases: {} };
|
|
1268
1395
|
for (const node of this.nodeIterator()) {
|
|
1269
|
-
buildUpAliases(node, xw,
|
|
1396
|
+
buildUpAliases(node, xw, data);
|
|
1270
1397
|
}
|
|
1271
|
-
writeAliases(xw,
|
|
1398
|
+
writeAliases(xw, data.aliases);
|
|
1272
1399
|
|
|
1273
1400
|
xw.visitedNode = {};
|
|
1274
1401
|
|
|
@@ -1281,10 +1408,8 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
|
|
|
1281
1408
|
|
|
1282
1409
|
// -------------- Dictionaries
|
|
1283
1410
|
const addressSpace = this.addressSpace;
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
// let find all DataType dictionary node corresponding to a given namespace
|
|
1287
|
-
// (have DataTypeDictionaryType)
|
|
1411
|
+
|
|
1412
|
+
const getDataTypeDescription = (opcBinaryTypeSystem: UAObject) => {
|
|
1288
1413
|
const nodeToBrowse = new BrowseDescription({
|
|
1289
1414
|
browseDirection: BrowseDirection.Forward,
|
|
1290
1415
|
includeSubtypes: false,
|
|
@@ -1295,12 +1420,9 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
|
|
|
1295
1420
|
});
|
|
1296
1421
|
const result = opcBinaryTypeSystem.browseNode(nodeToBrowse).filter((r) => r.nodeId.namespace === this.index);
|
|
1297
1422
|
assert(result.length <= 1);
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
dumpNodeInXml(xw, dataSystemType);
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1423
|
+
return result;
|
|
1424
|
+
};
|
|
1425
|
+
|
|
1304
1426
|
// -------------- DataTypes
|
|
1305
1427
|
const dataTypes = [...this._dataTypeIterator()].sort(sortByBrowseName);
|
|
1306
1428
|
if (dataTypes.length) {
|
|
@@ -1311,7 +1433,42 @@ NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
|
|
|
1311
1433
|
dumpNodeInXml(xw, dataType);
|
|
1312
1434
|
}
|
|
1313
1435
|
}
|
|
1436
|
+
|
|
1437
|
+
// --------------
|
|
1438
|
+
const opcBinaryTypeSystem = addressSpace.findNode(ObjectIds.OPCBinarySchema_TypeSystem) as UAObject;
|
|
1439
|
+
const opcXmlSchemaTypeSystem = addressSpace.findNode(ObjectIds.XmlSchema_TypeSystem) as UAObject;
|
|
1440
|
+
|
|
1441
|
+
if (opcBinaryTypeSystem) {
|
|
1442
|
+
// let find all DataType dictionary node corresponding to a given namespace
|
|
1443
|
+
// (have DataTypeDictionaryType)
|
|
1444
|
+
const result = getDataTypeDescription(opcBinaryTypeSystem);
|
|
1445
|
+
if (result.length === 1) {
|
|
1446
|
+
xw.writeComment("DataSystem - Binary");
|
|
1447
|
+
const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
|
|
1448
|
+
const types = dataSystemType.getComponents();
|
|
1449
|
+
for (const f of types) {
|
|
1450
|
+
dumpNodeInXml(xw, f);
|
|
1451
|
+
}
|
|
1452
|
+
dumpNodeInXml(xw, dataSystemType);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
if (opcXmlSchemaTypeSystem) {
|
|
1457
|
+
const result = getDataTypeDescription(opcXmlSchemaTypeSystem);
|
|
1458
|
+
if (result.length === 1) {
|
|
1459
|
+
xw.writeComment("DataSystem - Xml");
|
|
1460
|
+
const dataSystemType = addressSpace.findNode(result[0].nodeId)! as UAVariable;
|
|
1461
|
+
|
|
1462
|
+
const types = dataSystemType.getComponents();
|
|
1463
|
+
for (const f of types) {
|
|
1464
|
+
dumpNodeInXml(xw, f);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
dumpNodeInXml(xw, dataSystemType);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1314
1470
|
}
|
|
1471
|
+
|
|
1315
1472
|
// -------------- ObjectTypes
|
|
1316
1473
|
xw.writeComment("ObjectTypes");
|
|
1317
1474
|
const objectTypes = [...this._objectTypeIterator()].sort(sortByBrowseName);
|
|
@@ -10,6 +10,7 @@ import { BaseNode, UADataType, UAObjectType, UAReference, UAReferenceType, UAVar
|
|
|
10
10
|
import { BaseNode_getCache } from "./base_node_private";
|
|
11
11
|
import { ReferenceImpl } from "./reference_impl";
|
|
12
12
|
import { BaseNodeImpl } from "./base_node_impl";
|
|
13
|
+
import { NodeClass } from "node-opcua-data-model";
|
|
13
14
|
|
|
14
15
|
const HasSubTypeNodeId = resolveNodeId("HasSubtype");
|
|
15
16
|
|
|
@@ -96,8 +97,19 @@ export type UAType = UAReferenceType | UADataType | UAObjectType | UAVariableTyp
|
|
|
96
97
|
|
|
97
98
|
export function construct_isSupertypeOf<T extends UAType>(Class: typeof BaseNodeImpl): IsSupertypeOfFunc<T> {
|
|
98
99
|
return wrap_memoize(function (this: T, baseType: T | NodeIdLike): boolean {
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
if (!(baseType instanceof Class)) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
"expecting baseType to be " +
|
|
103
|
+
Class.name +
|
|
104
|
+
" but got " +
|
|
105
|
+
baseType.constructor.name +
|
|
106
|
+
" " +
|
|
107
|
+
NodeClass[(baseType as BaseNode).nodeClass]
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
if (!(this instanceof Class)) {
|
|
111
|
+
throw new Error("expecting this to be " + Class.name + " but got " + baseType.constructor.name);
|
|
112
|
+
}
|
|
101
113
|
return _slow_isSupertypeOf.call(this, Class, baseType as T);
|
|
102
114
|
}, hashBaseNode);
|
|
103
115
|
}
|