@itwin/ecschema-metadata 3.5.0-dev.4 → 3.5.0-dev.41

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.
Files changed (141) hide show
  1. package/CHANGELOG.md +39 -1
  2. package/lib/cjs/Constants.d.ts +23 -23
  3. package/lib/cjs/Constants.js +33 -33
  4. package/lib/cjs/Constants.js.map +1 -1
  5. package/lib/cjs/Context.d.ts +139 -139
  6. package/lib/cjs/Context.js +204 -204
  7. package/lib/cjs/DelayedPromise.d.ts +88 -88
  8. package/lib/cjs/DelayedPromise.js +91 -91
  9. package/lib/cjs/DelayedPromise.js.map +1 -1
  10. package/lib/cjs/Deserialization/AbstractParser.d.ts +45 -45
  11. package/lib/cjs/Deserialization/AbstractParser.js +11 -11
  12. package/lib/cjs/Deserialization/AbstractParser.js.map +1 -1
  13. package/lib/cjs/Deserialization/Helper.d.ts +251 -251
  14. package/lib/cjs/Deserialization/Helper.js +843 -843
  15. package/lib/cjs/Deserialization/Helper.js.map +1 -1
  16. package/lib/cjs/Deserialization/JsonParser.d.ts +165 -165
  17. package/lib/cjs/Deserialization/JsonParser.js +680 -680
  18. package/lib/cjs/Deserialization/JsonParser.js.map +1 -1
  19. package/lib/cjs/Deserialization/JsonProps.d.ts +282 -282
  20. package/lib/cjs/Deserialization/JsonProps.js +9 -9
  21. package/lib/cjs/Deserialization/JsonProps.js.map +1 -1
  22. package/lib/cjs/Deserialization/SchemaGraphUtil.d.ts +34 -34
  23. package/lib/cjs/Deserialization/SchemaGraphUtil.js +77 -77
  24. package/lib/cjs/Deserialization/SchemaGraphUtil.js.map +1 -1
  25. package/lib/cjs/Deserialization/XmlParser.d.ts +85 -85
  26. package/lib/cjs/Deserialization/XmlParser.js +973 -973
  27. package/lib/cjs/Deserialization/XmlParser.js.map +1 -1
  28. package/lib/cjs/Deserialization/XmlSerializationUtils.d.ts +54 -54
  29. package/lib/cjs/Deserialization/XmlSerializationUtils.js +174 -174
  30. package/lib/cjs/Deserialization/XmlSerializationUtils.js.map +1 -1
  31. package/lib/cjs/ECName.d.ts +30 -30
  32. package/lib/cjs/ECName.js +85 -85
  33. package/lib/cjs/ECName.js.map +1 -1
  34. package/lib/cjs/ECObjects.d.ts +162 -162
  35. package/lib/cjs/ECObjects.js +453 -453
  36. package/lib/cjs/ECObjects.js.map +1 -1
  37. package/lib/cjs/Exception.d.ts +43 -43
  38. package/lib/cjs/Exception.js +86 -86
  39. package/lib/cjs/Exception.js.map +1 -1
  40. package/lib/cjs/Interfaces.d.ts +66 -66
  41. package/lib/cjs/Interfaces.js +9 -9
  42. package/lib/cjs/Interfaces.js.map +1 -1
  43. package/lib/cjs/Metadata/Class.d.ts +243 -243
  44. package/lib/cjs/Metadata/Class.js +558 -558
  45. package/lib/cjs/Metadata/Class.js.map +1 -1
  46. package/lib/cjs/Metadata/Constant.d.ts +64 -64
  47. package/lib/cjs/Metadata/Constant.js +123 -123
  48. package/lib/cjs/Metadata/Constant.js.map +1 -1
  49. package/lib/cjs/Metadata/CustomAttribute.d.ts +23 -23
  50. package/lib/cjs/Metadata/CustomAttribute.js +27 -27
  51. package/lib/cjs/Metadata/CustomAttribute.js.map +1 -1
  52. package/lib/cjs/Metadata/CustomAttributeClass.d.ts +39 -39
  53. package/lib/cjs/Metadata/CustomAttributeClass.js +68 -68
  54. package/lib/cjs/Metadata/CustomAttributeClass.js.map +1 -1
  55. package/lib/cjs/Metadata/EntityClass.d.ts +77 -77
  56. package/lib/cjs/Metadata/EntityClass.js +230 -230
  57. package/lib/cjs/Metadata/EntityClass.js.map +1 -1
  58. package/lib/cjs/Metadata/Enumeration.d.ts +86 -86
  59. package/lib/cjs/Metadata/Enumeration.js +159 -159
  60. package/lib/cjs/Metadata/Enumeration.js.map +1 -1
  61. package/lib/cjs/Metadata/Format.d.ts +98 -98
  62. package/lib/cjs/Metadata/Format.js +242 -242
  63. package/lib/cjs/Metadata/Format.js.map +1 -1
  64. package/lib/cjs/Metadata/InvertedUnit.d.ts +49 -49
  65. package/lib/cjs/Metadata/InvertedUnit.js +97 -97
  66. package/lib/cjs/Metadata/InvertedUnit.js.map +1 -1
  67. package/lib/cjs/Metadata/KindOfQuantity.d.ts +65 -65
  68. package/lib/cjs/Metadata/KindOfQuantity.js +225 -225
  69. package/lib/cjs/Metadata/KindOfQuantity.js.map +1 -1
  70. package/lib/cjs/Metadata/Mixin.d.ts +54 -54
  71. package/lib/cjs/Metadata/Mixin.js +113 -113
  72. package/lib/cjs/Metadata/Mixin.js.map +1 -1
  73. package/lib/cjs/Metadata/OverrideFormat.d.ts +55 -55
  74. package/lib/cjs/Metadata/OverrideFormat.js +88 -88
  75. package/lib/cjs/Metadata/OverrideFormat.js.map +1 -1
  76. package/lib/cjs/Metadata/Phenomenon.d.ts +33 -33
  77. package/lib/cjs/Metadata/Phenomenon.js +59 -59
  78. package/lib/cjs/Metadata/Phenomenon.js.map +1 -1
  79. package/lib/cjs/Metadata/Property.d.ts +197 -197
  80. package/lib/cjs/Metadata/Property.js +491 -491
  81. package/lib/cjs/Metadata/Property.js.map +1 -1
  82. package/lib/cjs/Metadata/PropertyCategory.d.ts +39 -39
  83. package/lib/cjs/Metadata/PropertyCategory.js +61 -61
  84. package/lib/cjs/Metadata/PropertyCategory.js.map +1 -1
  85. package/lib/cjs/Metadata/RelationshipClass.d.ts +152 -152
  86. package/lib/cjs/Metadata/RelationshipClass.js +349 -349
  87. package/lib/cjs/Metadata/RelationshipClass.js.map +1 -1
  88. package/lib/cjs/Metadata/Schema.d.ts +291 -291
  89. package/lib/cjs/Metadata/Schema.js +520 -520
  90. package/lib/cjs/Metadata/Schema.js.map +1 -1
  91. package/lib/cjs/Metadata/SchemaItem.d.ts +61 -61
  92. package/lib/cjs/Metadata/SchemaItem.js +136 -136
  93. package/lib/cjs/Metadata/SchemaItem.js.map +1 -1
  94. package/lib/cjs/Metadata/Unit.d.ts +76 -76
  95. package/lib/cjs/Metadata/Unit.js +162 -162
  96. package/lib/cjs/Metadata/UnitSystem.d.ts +20 -20
  97. package/lib/cjs/Metadata/UnitSystem.js +29 -29
  98. package/lib/cjs/Metadata/UnitSystem.js.map +1 -1
  99. package/lib/cjs/PropertyTypes.d.ts +49 -49
  100. package/lib/cjs/PropertyTypes.js +91 -91
  101. package/lib/cjs/PropertyTypes.js.map +1 -1
  102. package/lib/cjs/SchemaJsonLocater.d.ts +34 -34
  103. package/lib/cjs/SchemaJsonLocater.js +42 -42
  104. package/lib/cjs/SchemaJsonLocater.js.map +1 -1
  105. package/lib/cjs/SchemaKey.d.ts +110 -110
  106. package/lib/cjs/SchemaKey.js +219 -219
  107. package/lib/cjs/SchemaKey.js.map +1 -1
  108. package/lib/cjs/SchemaLoader.d.ts +23 -23
  109. package/lib/cjs/SchemaLoader.js +47 -47
  110. package/lib/cjs/SchemaLoader.js.map +1 -1
  111. package/lib/cjs/SchemaPartVisitorDelegate.d.ts +274 -274
  112. package/lib/cjs/SchemaPartVisitorDelegate.js +212 -212
  113. package/lib/cjs/SchemaPartVisitorDelegate.js.map +1 -1
  114. package/lib/cjs/UnitConversion/Graph.d.ts +34 -34
  115. package/lib/cjs/UnitConversion/Graph.js +83 -83
  116. package/lib/cjs/UnitConversion/Graph.js.map +1 -1
  117. package/lib/cjs/UnitConversion/Parser.d.ts +8 -8
  118. package/lib/cjs/UnitConversion/Parser.js +42 -42
  119. package/lib/cjs/UnitConversion/Parser.js.map +1 -1
  120. package/lib/cjs/UnitConversion/UnitConversion.d.ts +45 -45
  121. package/lib/cjs/UnitConversion/UnitConversion.js +77 -77
  122. package/lib/cjs/UnitConversion/UnitConversion.js.map +1 -1
  123. package/lib/cjs/UnitConversion/UnitConverter.d.ts +39 -39
  124. package/lib/cjs/UnitConversion/UnitConverter.js +116 -116
  125. package/lib/cjs/UnitConversion/UnitConverter.js.map +1 -1
  126. package/lib/cjs/UnitConversion/UnitTree.d.ts +43 -43
  127. package/lib/cjs/UnitConversion/UnitTree.js +169 -169
  128. package/lib/cjs/UnitConversion/UnitTree.js.map +1 -1
  129. package/lib/cjs/UnitProvider/SchemaUnitProvider.d.ts +77 -77
  130. package/lib/cjs/UnitProvider/SchemaUnitProvider.js +236 -236
  131. package/lib/cjs/UnitProvider/SchemaUnitProvider.js.map +1 -1
  132. package/lib/cjs/Validation/SchemaWalker.d.ts +23 -23
  133. package/lib/cjs/Validation/SchemaWalker.js +53 -53
  134. package/lib/cjs/Validation/SchemaWalker.js.map +1 -1
  135. package/lib/cjs/ecschema-metadata.d.ts +51 -51
  136. package/lib/cjs/ecschema-metadata.js +96 -96
  137. package/lib/cjs/ecschema-metadata.js.map +1 -1
  138. package/lib/cjs/utils/SchemaGraph.d.ts +25 -25
  139. package/lib/cjs/utils/SchemaGraph.js +65 -65
  140. package/lib/cjs/utils/SchemaGraph.js.map +1 -1
  141. package/package.json +8 -8
@@ -1,974 +1,974 @@
1
- "use strict";
2
- /*---------------------------------------------------------------------------------------------
3
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
- * See LICENSE.md in the project root for license terms and full copyright notice.
5
- *--------------------------------------------------------------------------------------------*/
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.XmlParser = void 0;
8
- const core_bentley_1 = require("@itwin/core-bentley");
9
- const ECObjects_1 = require("../ECObjects");
10
- const Exception_1 = require("../Exception");
11
- const ECName_1 = require("../ECName");
12
- const AbstractParser_1 = require("./AbstractParser");
13
- const NON_ITEM_SCHEMA_ELEMENTS = ["ECSchemaReference", "ECCustomAttributes"];
14
- const ECXML_URI = "http://www\\.bentley\\.com/schemas/Bentley\\.ECXML";
15
- /** @internal */
16
- class XmlParser extends AbstractParser_1.AbstractParser {
17
- constructor(rawSchema) {
18
- super();
19
- this._rawSchema = rawSchema;
20
- const schemaInfo = rawSchema.documentElement;
21
- const schemaName = schemaInfo.getAttribute("schemaName");
22
- if (schemaName)
23
- this._schemaName = schemaName;
24
- this._schemaAlias = "";
25
- const schemaAlias = schemaInfo.getAttribute("alias");
26
- if (schemaAlias)
27
- this._schemaAlias = schemaAlias;
28
- this._schemaReferenceNames = new Map();
29
- const schemaVersion = schemaInfo.getAttribute("version");
30
- if (schemaVersion)
31
- this._schemaVersion = schemaVersion;
32
- const xmlNamespace = schemaInfo.getAttribute("xmlns");
33
- if (xmlNamespace) {
34
- this._xmlNamespace = xmlNamespace;
35
- this._ecXmlVersion = this.parseXmlNamespace(this._xmlNamespace);
36
- }
37
- this._schemaItems = new Map();
38
- this._mapIsPopulated = false;
39
- }
40
- parseSchema() {
41
- const schemaMetadata = this._rawSchema.documentElement;
42
- if ("ECSchema" !== schemaMetadata.nodeName)
43
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, "An ECSchema is missing the required metadata.");
44
- const schemaDefDuplicates = this.getElementChildrenByTagName(schemaMetadata, "ECSchema");
45
- if (schemaDefDuplicates.length > 1)
46
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, "An ECSchema has more than one ECSchema definition. Only one is allowed.");
47
- if (this._schemaName === undefined)
48
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `An ECSchema is missing a required 'schemaName' attribute`);
49
- if (this._schemaVersion === undefined)
50
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECSchema ${this._schemaName} is missing a required 'version' attribute`);
51
- if (this._xmlNamespace === undefined)
52
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECSchema ${this._schemaName} is missing a required 'xmlns' attribute`);
53
- if (this._ecXmlVersion === undefined)
54
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECSchema ${this._schemaName} has an invalid 'xmlns' attribute`);
55
- const alias = this.getRequiredAttribute(schemaMetadata, "alias", `The ECSchema ${this._schemaName} is missing a required 'alias' attribute`);
56
- const description = this.getOptionalAttribute(schemaMetadata, "description");
57
- const displayLabel = this.getOptionalAttribute(schemaMetadata, "displayLabel");
58
- const schemaProps = {
59
- name: this._schemaName,
60
- $schema: this._xmlNamespace,
61
- version: this._schemaVersion,
62
- alias,
63
- label: displayLabel,
64
- description,
65
- };
66
- return schemaProps;
67
- }
68
- *getReferences() {
69
- const schemaReferences = this.getElementChildrenByTagName(this._rawSchema.documentElement, "ECSchemaReference");
70
- for (const ref of schemaReferences) {
71
- yield this.getSchemaReference(ref);
72
- }
73
- }
74
- *getItems() {
75
- if (!this._mapIsPopulated) {
76
- const schemaItems = this.getSchemaChildren();
77
- for (const item of schemaItems) {
78
- let rawItemType = item.nodeName;
79
- if (NON_ITEM_SCHEMA_ELEMENTS.includes(rawItemType))
80
- continue;
81
- // Differentiate a Mixin from an EntityClass
82
- const customAttributesResult = this.getElementChildrenByTagName(item, "ECCustomAttributes");
83
- if (customAttributesResult.length > 0) {
84
- const customAttributes = customAttributesResult[0];
85
- const isMixinResult = this.getElementChildrenByTagName(customAttributes, "IsMixin");
86
- if (isMixinResult.length > 0)
87
- rawItemType = "Mixin";
88
- }
89
- const itemType = this.getSchemaItemType(rawItemType);
90
- if (itemType === undefined)
91
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `A SchemaItem in ${this._schemaName} has an invalid type. '${rawItemType}' is not a valid SchemaItem type.`);
92
- const itemName = this.getRequiredAttribute(item, "typeName", `A SchemaItem in ${this._schemaName} is missing the required 'typeName' attribute.`);
93
- if (!ECName_1.ECName.validate(itemName))
94
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidECName, `A SchemaItem in ${this._schemaName} has an invalid 'typeName' attribute. '${itemName}' is not a valid ECName.`);
95
- this._currentItemFullName = `${this._schemaName}.${itemName}`;
96
- this._schemaItems.set(itemName, [itemType, item]);
97
- yield [itemName, itemType, item];
98
- }
99
- this._mapIsPopulated = true;
100
- }
101
- else {
102
- for (const [itemName, [itemType, item]] of this._schemaItems) {
103
- this._currentItemFullName = `${this._schemaName}.${itemName}`;
104
- yield [itemName, itemType, item];
105
- }
106
- }
107
- }
108
- findItem(itemName) {
109
- if (!this._mapIsPopulated) {
110
- for (const item of this.getItems()) {
111
- if (item[0] === itemName) {
112
- this._currentItemFullName = `${this._schemaName}.${itemName}`;
113
- return item;
114
- }
115
- }
116
- }
117
- else {
118
- const values = this._schemaItems.get(itemName);
119
- if (undefined !== values) {
120
- const [itemType, item] = values;
121
- this._currentItemFullName = `${this._schemaName}.${itemName}`;
122
- return [itemName, itemType, item];
123
- }
124
- }
125
- return undefined;
126
- }
127
- parseEntityClass(xmlElement) {
128
- const classProps = this.getClassProps(xmlElement);
129
- const baseClasses = this.getElementChildrenByTagName(xmlElement, "BaseClass");
130
- let mixinElements;
131
- const mixins = new Array();
132
- // if it has just one BaseClass we assume it is a 'true' base class not a mixin
133
- if (baseClasses.length > 1) {
134
- mixinElements = baseClasses.slice(1);
135
- for (const mixin of mixinElements) {
136
- if (mixin.textContent) {
137
- const typeName = this.getQualifiedTypeName(mixin.textContent);
138
- mixins.push(typeName);
139
- }
140
- }
141
- }
142
- const entityClassProps = {
143
- ...classProps,
144
- mixins,
145
- };
146
- return entityClassProps;
147
- }
148
- parseMixin(xmlElement) {
149
- const classProps = this.getClassProps(xmlElement);
150
- const baseClasses = this.getElementChildrenByTagName(xmlElement, "BaseClass");
151
- // Mixins can only have one base class
152
- if (baseClasses.length > 1)
153
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} has more than one base class which is not allowed.`);
154
- const customAttributesResult = this.getElementChildrenByTagName(xmlElement, "ECCustomAttributes");
155
- if (customAttributesResult.length < 1)
156
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'IsMixin' tag.`);
157
- const customAttributes = customAttributesResult[0];
158
- const isMixinResult = this.getElementChildrenByTagName(customAttributes, "IsMixin");
159
- if (isMixinResult.length < 1)
160
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'IsMixin' tag.`);
161
- const mixinAttributes = isMixinResult[0];
162
- const appliesToResult = this.getElementChildrenByTagName(mixinAttributes, "AppliesToEntityClass");
163
- if (appliesToResult.length < 1)
164
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'AppliesToEntityClass' tag.`);
165
- const appliesToElement = appliesToResult[0];
166
- let appliesTo = appliesToElement.textContent;
167
- if (appliesTo === null || appliesTo.length === 0)
168
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'AppliesToEntityClass' tag.`);
169
- appliesTo = this.getQualifiedTypeName(appliesTo);
170
- const mixinProps = {
171
- ...classProps,
172
- appliesTo,
173
- };
174
- return mixinProps;
175
- }
176
- parseStructClass(xmlElement) {
177
- return this.getClassProps(xmlElement);
178
- }
179
- parseCustomAttributeClass(xmlElement) {
180
- const classProps = this.getClassProps(xmlElement);
181
- const appliesTo = this.getRequiredAttribute(xmlElement, "appliesTo", `The CustomAttributeClass ${this._currentItemFullName} is missing the required 'appliesTo' attribute.`);
182
- const customAttributeClassProps = {
183
- ...classProps,
184
- appliesTo,
185
- };
186
- return customAttributeClassProps;
187
- }
188
- parseRelationshipClass(xmlElement) {
189
- const classProps = this.getClassProps(xmlElement);
190
- const strength = this.getRequiredAttribute(xmlElement, "strength", `The RelationshipClass ${this._currentItemFullName} is missing the required 'strength' attribute.`);
191
- let strengthDirection = this.getOptionalAttribute(xmlElement, "strengthDirection");
192
- if (!strengthDirection)
193
- strengthDirection = (0, ECObjects_1.strengthDirectionToString)(ECObjects_1.StrengthDirection.Forward);
194
- const sourceResult = this.getElementChildrenByTagName(xmlElement, "Source");
195
- if (sourceResult.length !== 1) {
196
- if (sourceResult.length === 0)
197
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Source constraint tag.`);
198
- else
199
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} has more than one Source constraint tag. Only one is allowed.`);
200
- }
201
- const source = this.getRelationshipConstraintProps(sourceResult[0], true);
202
- const targetResult = this.getElementChildrenByTagName(xmlElement, "Target");
203
- if (targetResult.length !== 1) {
204
- if (targetResult.length === 0)
205
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Target constraint tag.`);
206
- else
207
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} has more than one Target constraint tag. Only one is allowed.`);
208
- }
209
- const target = this.getRelationshipConstraintProps(targetResult[0], false);
210
- return {
211
- ...classProps,
212
- strength,
213
- strengthDirection,
214
- source,
215
- target,
216
- };
217
- }
218
- parseEnumeration(xmlElement) {
219
- const itemProps = this.getSchemaItemProps(xmlElement);
220
- const enumType = this.getRequiredAttribute(xmlElement, "backingTypeName", `The Enumeration ${this._currentItemFullName} is missing the required 'backingTypeName' attribute.`);
221
- // TODO: This shouldn't be verified here. It's for the deserialize method to handle. The only reason it's currently done here so that the xml
222
- // value can be put in the correct type, number or string.
223
- let tempBackingType;
224
- if (/int/i.test(enumType))
225
- tempBackingType = ECObjects_1.PrimitiveType.Integer;
226
- else if (/string/i.test(enumType))
227
- tempBackingType = ECObjects_1.PrimitiveType.String;
228
- else
229
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidECJson, `The Enumeration ${this._currentItemFullName} has an invalid 'backingTypeName' attribute. It should be either "int" or "string".`);
230
- let isStrictString = this.getOptionalAttribute(xmlElement, "isStrict");
231
- if (isStrictString === undefined)
232
- isStrictString = "true";
233
- const isStrict = this.parseBoolean(isStrictString, `The Enumeration ${this._currentItemFullName} has an invalid 'isStrict' attribute. It should either be "true" or "false".`);
234
- const enumeratorElements = this.getElementChildrenByTagName(xmlElement, "ECEnumerator");
235
- const enumerators = new Array();
236
- for (const element of enumeratorElements) {
237
- const name = this.getRequiredAttribute(element, "name", `The Enumeration ${this._currentItemFullName} has an enumerator that is missing the required attribute 'name'.`);
238
- const valueString = this.getRequiredAttribute(element, "value", `The Enumeration ${this._currentItemFullName} has an enumerator that is missing the required attribute 'value'.`);
239
- let value = valueString;
240
- if (ECObjects_1.PrimitiveType.Integer === tempBackingType) {
241
- const numericValue = parseInt(valueString, 10);
242
- if (isNaN(numericValue))
243
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Enumeration ${this._currentItemFullName} of type "int" has an enumerator with a non-integer value.`);
244
- value = numericValue;
245
- }
246
- const label = this.getOptionalAttribute(element, "displayLabel");
247
- const description = this.getOptionalAttribute(element, "description");
248
- enumerators.push({
249
- name,
250
- value,
251
- label,
252
- description,
253
- });
254
- }
255
- return {
256
- ...itemProps,
257
- type: enumType,
258
- isStrict,
259
- enumerators,
260
- };
261
- }
262
- parseKindOfQuantity(xmlElement) {
263
- const itemProps = this.getSchemaItemProps(xmlElement);
264
- const relativeErrorString = this.getRequiredAttribute(xmlElement, "relativeError", `The KindOfQuantity ${this._currentItemFullName} is missing the required 'relativeError' attribute.`);
265
- const relativeError = parseFloat(relativeErrorString);
266
- if (isNaN(relativeError))
267
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The KindOfQuantity ${this._currentItemFullName} has an invalid 'relativeError' attribute. It should be a numeric value.`);
268
- const presentationUnitsString = this.getOptionalAttribute(xmlElement, "presentationUnits");
269
- let presentationUnits;
270
- if (presentationUnitsString)
271
- presentationUnits = this.getQualifiedPresentationUnits(presentationUnitsString.split(";"));
272
- let persistenceUnit = this.getRequiredAttribute(xmlElement, "persistenceUnit", `The KindOfQuantity ${this._currentItemFullName} is missing the required 'persistenceUnit' attribute.`);
273
- persistenceUnit = this.getQualifiedTypeName(persistenceUnit);
274
- return {
275
- ...itemProps,
276
- relativeError,
277
- presentationUnits,
278
- persistenceUnit,
279
- };
280
- }
281
- parsePropertyCategory(xmlElement) {
282
- const itemProps = this.getSchemaItemProps(xmlElement);
283
- const priorityString = this.getRequiredAttribute(xmlElement, "priority", `The PropertyCategory ${this._currentItemFullName} is missing the required 'priority' attribute.`);
284
- const priority = parseInt(priorityString, 10);
285
- if (isNaN(priority))
286
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The PropertyCategory ${this._currentItemFullName} has an invalid 'priority' attribute. It should be a numeric value.`);
287
- return {
288
- ...itemProps,
289
- priority,
290
- };
291
- }
292
- parseUnit(xmlElement) {
293
- const itemProps = this.getSchemaItemProps(xmlElement);
294
- let phenomenon = this.getRequiredAttribute(xmlElement, "phenomenon", `The Unit ${this._currentItemFullName} is missing the required 'phenomenon' attribute.`);
295
- let unitSystem = this.getRequiredAttribute(xmlElement, "unitSystem", `The Unit ${this._currentItemFullName} is missing the required 'unitSystem' attribute.`);
296
- const definition = this.getRequiredAttribute(xmlElement, "definition", `The Unit ${this._currentItemFullName} is missing the required 'definition' attribute.`);
297
- const numerator = this.getOptionalFloatAttribute(xmlElement, "numerator", `The Unit ${this._currentItemFullName} has an invalid 'numerator' attribute. It should be a numeric value.`);
298
- const denominator = this.getOptionalFloatAttribute(xmlElement, "denominator", `The Unit ${this._currentItemFullName} has an invalid 'denominator' attribute. It should be a numeric value.`);
299
- const offset = this.getOptionalFloatAttribute(xmlElement, "offset", `The Unit ${this._currentItemFullName} has an invalid 'offset' attribute. It should be a numeric value.`);
300
- phenomenon = this.getQualifiedTypeName(phenomenon);
301
- unitSystem = this.getQualifiedTypeName(unitSystem);
302
- return {
303
- ...itemProps,
304
- phenomenon,
305
- unitSystem,
306
- definition,
307
- numerator,
308
- denominator,
309
- offset,
310
- };
311
- }
312
- parseInvertedUnit(xmlElement) {
313
- const itemProps = this.getSchemaItemProps(xmlElement);
314
- let invertsUnit = this.getRequiredAttribute(xmlElement, "invertsUnit", `The InvertedUnit ${this._currentItemFullName} is missing the required 'invertsUnit' attribute.`);
315
- let unitSystem = this.getRequiredAttribute(xmlElement, "unitSystem", `The InvertedUnit ${this._currentItemFullName} is missing the required 'unitSystem' attribute.`);
316
- invertsUnit = this.getQualifiedTypeName(invertsUnit);
317
- unitSystem = this.getQualifiedTypeName(unitSystem);
318
- return {
319
- ...itemProps,
320
- invertsUnit,
321
- unitSystem,
322
- };
323
- }
324
- parseConstant(xmlElement) {
325
- const itemProps = this.getSchemaItemProps(xmlElement);
326
- let phenomenon = this.getRequiredAttribute(xmlElement, "phenomenon", `The Constant ${this._currentItemFullName} is missing the required 'phenomenon' attribute.`);
327
- const definition = this.getRequiredAttribute(xmlElement, "definition", `The Constant ${this._currentItemFullName} is missing the required 'definition' attribute.`);
328
- const numerator = this.getOptionalFloatAttribute(xmlElement, "numerator", `The Constant ${this._currentItemFullName} has an invalid 'numerator' attribute. It should be a numeric value.`);
329
- const denominator = this.getOptionalFloatAttribute(xmlElement, "denominator", `The Constant ${this._currentItemFullName} has an invalid 'denominator' attribute. It should be a numeric value.`);
330
- phenomenon = this.getQualifiedTypeName(phenomenon);
331
- return {
332
- ...itemProps,
333
- phenomenon,
334
- definition,
335
- numerator,
336
- denominator,
337
- };
338
- }
339
- parsePhenomenon(xmlElement) {
340
- const itemProps = this.getSchemaItemProps(xmlElement);
341
- const definition = this.getRequiredAttribute(xmlElement, "definition", `The Phenomenon ${this._currentItemFullName} is missing the required 'definition' attribute.`);
342
- return {
343
- ...itemProps,
344
- definition,
345
- };
346
- }
347
- parseFormat(xmlElement) {
348
- const itemProps = this.getSchemaItemProps(xmlElement);
349
- const formatType = this.getRequiredAttribute(xmlElement, "type", `The Format ${this._currentItemFullName} is missing the required 'type' attribute.`);
350
- const precision = this.getOptionalIntAttribute(xmlElement, "precision", `The Format ${this._currentItemFullName} has an invalid 'precision' attribute. It should be a numeric value.`);
351
- const roundFactor = this.getOptionalFloatAttribute(xmlElement, "roundFactor", `The Format ${this._currentItemFullName} has an invalid 'roundFactor' attribute. It should be a numeric value.`);
352
- const minWidth = this.getOptionalIntAttribute(xmlElement, "minWidth", `The Format ${this._currentItemFullName} has an invalid 'minWidth' attribute. It should be a numeric value.`);
353
- const showSignOption = this.getOptionalAttribute(xmlElement, "showSignOption");
354
- const formatTraitsString = this.getRequiredAttribute(xmlElement, "formatTraits", `The Format ${this._currentItemFullName} is missing the required 'formatTraits' attribute.`);
355
- const formatTraits = formatTraitsString.split("|");
356
- const decimalSeparator = this.getOptionalAttribute(xmlElement, "decimalSeparator");
357
- const thousandSeparator = this.getOptionalAttribute(xmlElement, "thousandSeparator");
358
- const uomSeparator = this.getOptionalAttribute(xmlElement, "uomSeparator");
359
- const scientificType = this.getOptionalAttribute(xmlElement, "scientificType");
360
- const stationOffsetSize = this.getOptionalIntAttribute(xmlElement, "stationOffsetSize", `The Format ${this._currentItemFullName} has an invalid 'stationOffsetSize' attribute. It should be a numeric value.`);
361
- const stationSeparator = this.getOptionalAttribute(xmlElement, "stationSeparator");
362
- let composite;
363
- const compositeResult = this.getElementChildrenByTagName(xmlElement, "Composite");
364
- if (compositeResult.length > 0) {
365
- const compositeElement = compositeResult[0];
366
- const spacer = this.getOptionalAttribute(compositeElement, "spacer");
367
- const includeZeroString = this.getOptionalAttribute(compositeElement, "includeZero");
368
- let includeZero;
369
- if (includeZeroString) {
370
- includeZero = this.parseBoolean(includeZeroString, `The Format ${this._currentItemFullName} has a Composite with an invalid 'includeZero' attribute. It should be either "true" or "false".`);
371
- }
372
- const units = new Array();
373
- const unitsResult = this.getElementChildrenByTagName(compositeElement, "Unit");
374
- if (unitsResult.length < 1)
375
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Format ${this._currentItemFullName} has an invalid 'Composite' element. It should have 1-4 Unit elements.`);
376
- for (const unit of unitsResult) {
377
- let name = unit.textContent;
378
- if (null === name || 0 === name.length)
379
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Format ${this._currentItemFullName} has a Composite with an invalid Unit. One of the Units is missing the required 'name' attribute.`);
380
- const label = this.getOptionalAttribute(unit, "label");
381
- name = this.getQualifiedTypeName(name);
382
- units.push({ name, label });
383
- }
384
- composite = {
385
- spacer,
386
- includeZero,
387
- units,
388
- };
389
- }
390
- return {
391
- ...itemProps,
392
- type: formatType,
393
- precision,
394
- roundFactor,
395
- minWidth,
396
- showSignOption,
397
- formatTraits,
398
- decimalSeparator,
399
- thousandSeparator,
400
- uomSeparator,
401
- scientificType,
402
- stationOffsetSize,
403
- stationSeparator,
404
- composite,
405
- };
406
- }
407
- parseUnitSystem(xmlElement) {
408
- return this.getClassProps(xmlElement);
409
- }
410
- *getProperties(xmlElement, itemName) {
411
- const propertyTagRegex = /EC((Struct(Array)?)|Array|Navigation)?Property/;
412
- const children = this.getElementChildrenByTagName(xmlElement, propertyTagRegex);
413
- for (const child of children) {
414
- const childType = child.nodeName;
415
- const propertyName = this.getRequiredAttribute(child, "propertyName", `An ECProperty in ${itemName} is missing the required 'propertyName' attribute.`);
416
- const propertyType = this.getPropertyType(childType);
417
- // This may not be needed, just a failsafe if the regex is faulty
418
- if (propertyType === undefined)
419
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECProperty ${itemName}.${propertyName} has an invalid type. ${childType} is not a valid ECProperty type.`);
420
- yield [propertyName, propertyType, child];
421
- }
422
- }
423
- parsePrimitiveProperty(xmlElement) {
424
- const propertyProps = this.getPrimitiveOrEnumPropertyBaseProps(xmlElement);
425
- const typeName = this.getPropertyTypeName(xmlElement);
426
- const primitivePropertyProps = { ...propertyProps, typeName };
427
- return primitivePropertyProps;
428
- }
429
- parseStructProperty(xmlElement) {
430
- const propertyProps = this.getPropertyProps(xmlElement);
431
- const typeName = this.getPropertyTypeName(xmlElement);
432
- const structPropertyProps = { ...propertyProps, typeName };
433
- return structPropertyProps;
434
- }
435
- parsePrimitiveArrayProperty(xmlElement) {
436
- const typeName = this.getPropertyTypeName(xmlElement);
437
- const propertyProps = this.getPrimitiveOrEnumPropertyBaseProps(xmlElement);
438
- const minAndMaxOccurs = this.getPropertyMinAndMaxOccurs(xmlElement);
439
- return {
440
- ...propertyProps,
441
- ...minAndMaxOccurs,
442
- typeName,
443
- };
444
- }
445
- parseStructArrayProperty(xmlElement) {
446
- const propertyProps = this.getPropertyProps(xmlElement);
447
- const typeName = this.getPropertyTypeName(xmlElement);
448
- const minAndMaxOccurs = this.getPropertyMinAndMaxOccurs(xmlElement);
449
- return {
450
- ...propertyProps,
451
- ...minAndMaxOccurs,
452
- typeName,
453
- };
454
- }
455
- parseNavigationProperty(xmlElement) {
456
- const propName = this.getPropertyName(xmlElement);
457
- const propertyProps = this.getPropertyProps(xmlElement);
458
- let relationshipName = this.getRequiredAttribute(xmlElement, "relationshipName", `The ECNavigationProperty ${this._currentItemFullName}.${propName} is missing the required 'relationshipName' property.`);
459
- const direction = this.getRequiredAttribute(xmlElement, "direction", `The ECNavigationProperty ${this._currentItemFullName}.${propName} is missing the required 'direction' property.`);
460
- relationshipName = this.getQualifiedTypeName(relationshipName);
461
- return {
462
- ...propertyProps,
463
- relationshipName,
464
- direction,
465
- };
466
- }
467
- getSchemaCustomAttributeProviders() {
468
- return this.getCustomAttributeProviders(this._rawSchema.documentElement, "Schema", this._schemaName);
469
- }
470
- getClassCustomAttributeProviders(xmlElement) {
471
- return this.getCustomAttributeProviders(xmlElement, "ECClass", this._currentItemFullName);
472
- }
473
- getPropertyCustomAttributeProviders(xmlElement) {
474
- const propName = this.getPropertyName(xmlElement);
475
- return this.getCustomAttributeProviders(xmlElement, "ECProperty", `${this._currentItemFullName}.${propName}`);
476
- }
477
- getRelationshipConstraintCustomAttributeProviders(xmlElement) {
478
- const sourceResult = this.getElementChildrenByTagName(xmlElement, "Source");
479
- if (sourceResult.length < 1)
480
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Source constraint tag.`);
481
- const sourceElement = sourceResult[0];
482
- const sourceCustomAttributes = this.getCustomAttributeProviders(sourceElement, "Source Constraint of", this._currentItemFullName);
483
- const targetResult = this.getElementChildrenByTagName(xmlElement, "Target");
484
- if (targetResult.length < 1)
485
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Target constraint tag.`);
486
- const targetElement = targetResult[0];
487
- const targetCustomAttributes = this.getCustomAttributeProviders(targetElement, "Source Constraint of", this._currentItemFullName);
488
- return [sourceCustomAttributes, targetCustomAttributes];
489
- }
490
- getElementChildren(xmlElement) {
491
- // NodeListOf<T> does not define [Symbol.iterator]
492
- const children = Array.from(xmlElement.childNodes).filter((child) => {
493
- // (node.nodeType === 1) implies instanceof Element
494
- // https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/children#Polyfill
495
- return child.nodeType === 1;
496
- });
497
- return children;
498
- }
499
- getElementChildrenByTagName(xmlElement, tagName) {
500
- const children = this.getElementChildren(xmlElement);
501
- if ("*" === tagName)
502
- return children;
503
- let result;
504
- if (typeof tagName === "string") {
505
- result = children.filter((child) => {
506
- return tagName.toLowerCase() === child.nodeName.toLowerCase();
507
- });
508
- }
509
- else {
510
- result = children.filter((child) => {
511
- return tagName.test(child.nodeName);
512
- });
513
- }
514
- return result;
515
- }
516
- getOptionalAttribute(xmlElement, attributeName) {
517
- if (!xmlElement.hasAttribute(attributeName))
518
- return undefined;
519
- const result = xmlElement.getAttribute(attributeName);
520
- // The typings for the return value of getAttribute do not match that of xmldom
521
- // xmldom returns an empty string instead of null
522
- // However Typescript will still treat result as a union type without this check
523
- // Hence this is needed for tsc to compile
524
- if (result === null)
525
- return undefined;
526
- return result;
527
- }
528
- getOptionalFloatAttribute(xmlElement, attributeName, parseErrorMsg) {
529
- const resultString = this.getOptionalAttribute(xmlElement, attributeName);
530
- let result;
531
- if (resultString) {
532
- result = parseFloat(resultString);
533
- if (isNaN(result))
534
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, parseErrorMsg);
535
- }
536
- return result;
537
- }
538
- getOptionalIntAttribute(xmlElement, attributeName, parseErrorMsg) {
539
- const resultString = this.getOptionalAttribute(xmlElement, attributeName);
540
- let result;
541
- if (resultString) {
542
- result = parseInt(resultString, 10);
543
- if (isNaN(result))
544
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, parseErrorMsg);
545
- }
546
- return result;
547
- }
548
- parseBoolean(text, parseErrorMsg) {
549
- const textString = text.toLowerCase();
550
- if ("true" === textString)
551
- return true;
552
- else if ("false" === textString)
553
- return false;
554
- else
555
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, parseErrorMsg);
556
- }
557
- getRequiredAttribute(xmlElement, attributeName, errorMsg) {
558
- if (!xmlElement.hasAttribute(attributeName))
559
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, errorMsg);
560
- const result = xmlElement.getAttribute(attributeName);
561
- if (result === null)
562
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, errorMsg);
563
- return result;
564
- }
565
- getSchemaReference(xmlElement) {
566
- const alias = this.getRequiredAttribute(xmlElement, "alias", `The schema ${this._schemaName} has an invalid ECSchemaReference attribute. One of the references is missing the required 'alias' attribute.`);
567
- const name = this.getRequiredAttribute(xmlElement, "name", `The schema ${this._schemaName} has an invalid ECSchemaReference attribute. One of the references is missing the required 'name' attribute.`);
568
- const version = this.getRequiredAttribute(xmlElement, "version", `The schema ${this._schemaName} has an invalid ECSchemaReference attribute. One of the references is missing the required 'version' attribute.`);
569
- if (!this._schemaReferenceNames.has(alias.toLowerCase()))
570
- this._schemaReferenceNames.set(alias.toLowerCase(), name);
571
- return {
572
- name,
573
- version,
574
- };
575
- }
576
- getSchemaItemType(rawType) {
577
- switch (rawType.toLowerCase()) {
578
- case "ecentityclass": return "EntityClass";
579
- case "mixin": return "Mixin";
580
- case "ecstructclass": return "StructClass";
581
- case "eccustomattributeclass": return "CustomAttributeClass";
582
- case "ecrelationshipclass": return "RelationshipClass";
583
- case "ecenumeration": return "Enumeration";
584
- case "kindofquantity": return "KindOfQuantity";
585
- case "propertycategory": return "PropertyCategory";
586
- case "unit": return "Unit";
587
- case "invertedunit": return "InvertedUnit";
588
- case "constant": return "Constant";
589
- case "phenomenon": return "Phenomenon";
590
- case "unitsystem": return "UnitSystem";
591
- case "format": return "Format";
592
- }
593
- return undefined;
594
- }
595
- getSchemaChildren() {
596
- const schemaMetadata = this._rawSchema.documentElement;
597
- return this.getElementChildren(schemaMetadata);
598
- }
599
- getSchemaItemProps(xmlElement) {
600
- const displayLabel = this.getOptionalAttribute(xmlElement, "displayLabel");
601
- const description = this.getOptionalAttribute(xmlElement, "description");
602
- return {
603
- description,
604
- label: displayLabel,
605
- };
606
- }
607
- getClassProps(xmlElement) {
608
- const itemProps = this.getSchemaItemProps(xmlElement);
609
- const modifier = this.getOptionalAttribute(xmlElement, "modifier");
610
- let baseClass = null;
611
- const baseClasses = this.getElementChildrenByTagName(xmlElement, "BaseClass");
612
- if (baseClasses.length > 0) {
613
- // We are assuming here that the first BaseClass is the 'real' one - the rest are mixins
614
- // This is not a finalized approach as this could lead to unsupported schemas
615
- baseClass = baseClasses[0].textContent;
616
- }
617
- baseClass = baseClass ? this.getQualifiedTypeName(baseClass) : undefined;
618
- return {
619
- ...itemProps,
620
- modifier,
621
- baseClass,
622
- };
623
- }
624
- getRelationshipConstraintProps(xmlElement, isSource) {
625
- const constraintName = `${(isSource) ? "Source" : "Target"} Constraint of ${this._currentItemFullName}`;
626
- const multiplicity = this.getRequiredAttribute(xmlElement, "multiplicity", `The ${constraintName} is missing the required 'multiplicity' attribute.`);
627
- const roleLabel = this.getRequiredAttribute(xmlElement, "roleLabel", `The ${constraintName} is missing the required 'roleLabel' attribute.`);
628
- const polymorphicString = this.getRequiredAttribute(xmlElement, "polymorphic", `The ${constraintName} is missing the required 'polymorphic' attribute.`);
629
- const polymorphic = this.parseBoolean(polymorphicString, `The ${constraintName} has an invalid 'polymorphic' attribute. It should either be "true" or "false".`);
630
- let abstractConstraint = this.getOptionalAttribute(xmlElement, "abstractConstraint");
631
- if (undefined !== abstractConstraint)
632
- abstractConstraint = this.getQualifiedTypeName(abstractConstraint);
633
- const constraintClasses = new Array();
634
- const constraintClassesResult = this.getElementChildrenByTagName(xmlElement, "Class");
635
- if (constraintClassesResult.length < 1)
636
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ${constraintName} is missing the required Class tags.`);
637
- for (const constraintClass of constraintClassesResult) {
638
- let constraintClassId = constraintClass.getAttribute("class");
639
- if (null === constraintClassId || 0 === constraintClassId.length)
640
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ${constraintName} has a Class that is missing the required 'class' attribute.`);
641
- constraintClassId = this.getQualifiedTypeName(constraintClassId);
642
- constraintClasses.push(constraintClassId);
643
- }
644
- return {
645
- multiplicity,
646
- roleLabel,
647
- polymorphic,
648
- abstractConstraint,
649
- constraintClasses,
650
- };
651
- }
652
- getPropertyType(propType) {
653
- switch (propType) {
654
- case "ECNavigationProperty": return "navigationproperty";
655
- case "ECStructProperty": return "structproperty";
656
- case "ECArrayProperty": return "primitivearrayproperty";
657
- case "ECStructArrayProperty": return "structarrayproperty";
658
- case "ECProperty": return "primitiveproperty";
659
- default: return undefined;
660
- }
661
- }
662
- getPropertyName(xmlElement) {
663
- return this.getRequiredAttribute(xmlElement, "propertyName", `An ECProperty in ${this._currentItemFullName} is missing the required 'propertyName' attribute.`);
664
- }
665
- getPropertyProps(xmlElement) {
666
- const propName = this.getPropertyName(xmlElement);
667
- const propType = this.getPropertyType(xmlElement.nodeName);
668
- if (propType === undefined)
669
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid type. ${propType} is not a valid ECProperty type.`);
670
- const label = this.getOptionalAttribute(xmlElement, "displayLabel");
671
- const description = this.getOptionalAttribute(xmlElement, "description");
672
- const readOnlyString = this.getOptionalAttribute(xmlElement, "readOnly");
673
- let isReadOnly;
674
- if (readOnlyString) {
675
- isReadOnly = this.parseBoolean(readOnlyString, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'readOnly' attribute. It should be either "true" or "false".`);
676
- }
677
- let category = this.getOptionalAttribute(xmlElement, "category");
678
- const priority = this.getOptionalIntAttribute(xmlElement, "priority", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'priority' attribute. It should be a numeric value.`);
679
- const inheritedString = this.getOptionalAttribute(xmlElement, "inherited");
680
- let inherited;
681
- if (inheritedString) {
682
- inherited = this.parseBoolean(inheritedString, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'inherited' attribute. It should be either "true" or "false".`);
683
- }
684
- let kindOfQuantity = this.getOptionalAttribute(xmlElement, "kindOfQuantity");
685
- if (kindOfQuantity)
686
- kindOfQuantity = this.getQualifiedTypeName(kindOfQuantity);
687
- if (category)
688
- category = this.getQualifiedTypeName(category);
689
- return {
690
- name: propName,
691
- type: propType,
692
- description,
693
- label,
694
- isReadOnly,
695
- category,
696
- priority,
697
- inherited,
698
- kindOfQuantity,
699
- };
700
- }
701
- getPropertyTypeName(xmlElement) {
702
- const propName = this.getPropertyName(xmlElement);
703
- const rawTypeName = this.getRequiredAttribute(xmlElement, "typeName", `The ECProperty ${this._currentItemFullName}.${propName} is missing the required 'typeName' attribute.`);
704
- // If not a primitive type, we must prepend the schema name.
705
- const primitiveType = (0, ECObjects_1.parsePrimitiveType)(rawTypeName);
706
- if (primitiveType)
707
- return rawTypeName;
708
- return this.getQualifiedTypeName(rawTypeName);
709
- }
710
- getPrimitiveOrEnumPropertyBaseProps(xmlElement) {
711
- const propertyProps = this.getPropertyProps(xmlElement);
712
- const propName = propertyProps.name;
713
- const extendedTypeName = this.getOptionalAttribute(xmlElement, "extendedTypeName");
714
- const minLength = this.getOptionalIntAttribute(xmlElement, "minimumLength", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'minimumLength' attribute. It should be a numeric value.`);
715
- const maxLength = this.getOptionalIntAttribute(xmlElement, "maximumLength", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'maximumLength' attribute. It should be a numeric value.`);
716
- const minValue = this.getOptionalIntAttribute(xmlElement, "minimumValue", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'minimumValue' attribute. It should be a numeric value.`);
717
- const maxValue = this.getOptionalIntAttribute(xmlElement, "maximumValue", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'maximumValue' attribute. It should be a numeric value.`);
718
- return {
719
- ...propertyProps,
720
- extendedTypeName,
721
- minLength,
722
- maxLength,
723
- minValue,
724
- maxValue,
725
- };
726
- }
727
- getPropertyMinAndMaxOccurs(xmlElement) {
728
- const propName = this.getPropertyName(xmlElement);
729
- const minOccurs = this.getOptionalIntAttribute(xmlElement, "minOccurs", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'minOccurs' attribute. It should be a numeric value.`);
730
- const maxOccursStr = this.getOptionalAttribute(xmlElement, "maxOccurs");
731
- let maxOccurs;
732
- if ("unbounded" === maxOccursStr)
733
- maxOccurs = 2147483647; // TODO: This should be using the INT32_MAX variable.
734
- else if (undefined !== maxOccursStr) {
735
- maxOccurs = parseInt(maxOccursStr, 10);
736
- if (isNaN(maxOccurs))
737
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'maxOccurs' attribute. It should be a numeric value.`);
738
- }
739
- return { minOccurs, maxOccurs };
740
- }
741
- *getCustomAttributeProviders(xmlElement, type, _name) {
742
- const customAttributesResult = this.getElementChildrenByTagName(xmlElement, "ECCustomAttributes");
743
- if (customAttributesResult.length < 1)
744
- return;
745
- const attributes = this.getElementChildren(customAttributesResult[0]);
746
- for (const attribute of attributes) {
747
- if ("ECClass" === type && "IsMixin" === attribute.tagName)
748
- continue;
749
- yield this.getCustomAttributeProvider(attribute);
750
- }
751
- }
752
- getCustomAttributeProvider(xmlCustomAttribute) {
753
- (0, core_bentley_1.assert)(this._ecXmlVersion !== undefined);
754
- let ns = xmlCustomAttribute.getAttribute("xmlns");
755
- if (!ns) {
756
- (0, core_bentley_1.assert)(this._schemaName !== undefined);
757
- (0, core_bentley_1.assert)(this._schemaVersion !== undefined);
758
- ns = `${this._schemaName}.${this._schemaVersion}`;
759
- }
760
- if (null === ns || !this.isSchemaFullNameValidForVersion(ns, this._ecXmlVersion))
761
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Custom attribute namespaces must contain a valid 3.2 full schema name in the form <schemaName>.RR.ww.mm.`);
762
- const schemaNameParts = ns.split(".");
763
- const className = `${schemaNameParts[0]}.${xmlCustomAttribute.tagName}`;
764
- const properties = this.getElementChildren(xmlCustomAttribute);
765
- const provider = (caClass) => {
766
- return this.addCAPropertyValues(caClass, properties);
767
- };
768
- return [className, provider];
769
- }
770
- addCAPropertyValues(caClass, propertyElements) {
771
- const instance = { className: caClass.fullName };
772
- if (!caClass.properties)
773
- return instance;
774
- for (const propertyElement of propertyElements) {
775
- const value = this.readPropertyValue(propertyElement, caClass);
776
- if (value !== undefined)
777
- instance[propertyElement.tagName] = value;
778
- }
779
- return instance;
780
- }
781
- readPropertyValue(propElement, parentClass) {
782
- const propertyClass = parentClass.getPropertySync(propElement.tagName);
783
- if (!propertyClass)
784
- return;
785
- if (propertyClass.isArray())
786
- return this.readArrayPropertyValue(propElement, propertyClass);
787
- let enumeration;
788
- if (propertyClass.isPrimitive()) {
789
- if (propertyClass.isEnumeration() && propertyClass.enumeration) {
790
- enumeration = propertyClass.schema.lookupItemSync(propertyClass.enumeration.fullName);
791
- if (!enumeration)
792
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.ClassNotFound, `The Enumeration class '${propertyClass.enumeration.fullName}' could not be found.`);
793
- }
794
- const primitiveType = enumeration && enumeration.type ? enumeration.type : (propertyClass).primitiveType;
795
- return this.readPrimitivePropertyValue(propElement, primitiveType);
796
- }
797
- if (propertyClass.isStruct())
798
- return this.readStructPropertyValue(propElement, propertyClass.structClass);
799
- return undefined;
800
- }
801
- readArrayPropertyValue(propElement, propertyClass) {
802
- if (propertyClass.isPrimitive())
803
- return this.readPrimitiveArrayValues(propElement, propertyClass.primitiveType);
804
- if (propertyClass.isStruct())
805
- return this.readStructArrayValues(propElement, propertyClass);
806
- return undefined;
807
- }
808
- readPrimitiveArrayValues(propElement, primitiveType) {
809
- const typeName = (0, ECObjects_1.primitiveTypeToString)(primitiveType);
810
- const children = this.getElementChildrenByTagName(propElement, typeName);
811
- const values = [];
812
- for (const child of children) {
813
- const value = this.readPrimitivePropertyValue(child, primitiveType);
814
- values.push(value);
815
- }
816
- return values;
817
- }
818
- readStructArrayValues(propElement, propertyClass) {
819
- const children = this.getElementChildren(propElement);
820
- const values = [];
821
- for (const child of children) {
822
- const value = this.readStructPropertyValue(child, propertyClass.structClass);
823
- values.push(value);
824
- }
825
- return values;
826
- }
827
- readStructPropertyValue(propElement, structClass) {
828
- const structObj = {};
829
- const children = this.getElementChildren(propElement);
830
- for (const child of children) {
831
- const value = this.readPropertyValue(child, structClass);
832
- if (value !== undefined)
833
- structObj[child.tagName] = value;
834
- }
835
- return structObj;
836
- }
837
- readPrimitivePropertyValue(propElement, primitiveType) {
838
- if (!propElement.textContent)
839
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Primitive property '${propElement.tagName}' has an invalid property value.`);
840
- // TODO: Mapping all primitive types to string, number and boolean
841
- // for now. Need to review with IModelJs.
842
- switch (primitiveType) {
843
- case ECObjects_1.PrimitiveType.String:
844
- case ECObjects_1.PrimitiveType.Binary: /** TODO - Currently treated as strings */
845
- case ECObjects_1.PrimitiveType.IGeometry: /** TODO - Currently treated as strings */
846
- return propElement.textContent;
847
- case ECObjects_1.PrimitiveType.DateTime:
848
- return this.getDatePropertyValue(propElement.textContent, propElement.tagName);
849
- case ECObjects_1.PrimitiveType.Point2d:
850
- return this.getPoint2DPropertyValue(propElement.textContent, propElement.tagName);
851
- case ECObjects_1.PrimitiveType.Point3d:
852
- return this.getPoint3DPropertyValue(propElement.textContent, propElement.tagName);
853
- case ECObjects_1.PrimitiveType.Boolean:
854
- return this.getBooleanPropertyValue(propElement.textContent, propElement.tagName);
855
- case ECObjects_1.PrimitiveType.Integer:
856
- case ECObjects_1.PrimitiveType.Long:
857
- return this.getIntegerPropertyValue(propElement.textContent, propElement.tagName);
858
- case ECObjects_1.PrimitiveType.Double:
859
- return this.getDoublePropertyValue(propElement.textContent, propElement.tagName);
860
- default:
861
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Primitive property '${propElement.tagName}' has an invalid primitive type.`);
862
- }
863
- }
864
- getBooleanPropertyValue(propValue, propName) {
865
- if (propValue.toLowerCase() === "true" ||
866
- Number.parseInt(propValue, 10) > 0) {
867
- return true;
868
- }
869
- else if (propValue.toLowerCase() === "false" ||
870
- Number.parseInt(propValue, 10) === 0) {
871
- return false;
872
- }
873
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. An boolean value was expected.`);
874
- }
875
- getIntegerPropertyValue(propValue, propName) {
876
- const result = Number.parseFloat(propValue);
877
- if (isNaN(result) || result % 1 !== 0)
878
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. An integer value was expected.`);
879
- return result;
880
- }
881
- getDatePropertyValue(propValue, propName) {
882
- const result = Number.parseInt(propValue, 10);
883
- if (isNaN(result))
884
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A date in milliseconds was expected.`);
885
- return new Date(result);
886
- }
887
- getDoublePropertyValue(propValue, propName) {
888
- const result = Number.parseFloat(propValue);
889
- if (isNaN(result))
890
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A double value was expected.`);
891
- return result;
892
- }
893
- getPoint2DPropertyValue(propValue, propName) {
894
- const result = propValue.split(",");
895
- if (result.length !== 2) {
896
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 2D value was expected.`);
897
- }
898
- const x = Number.parseFloat(result[0]);
899
- const y = Number.parseFloat(result[1]);
900
- if (isNaN(x) || isNaN(y))
901
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 2D value was expected.`);
902
- return { x, y };
903
- }
904
- getPoint3DPropertyValue(propValue, propName) {
905
- const result = propValue.split(",");
906
- if (result.length !== 3) {
907
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 3D value was expected.`);
908
- }
909
- const x = Number.parseFloat(result[0]);
910
- const y = Number.parseFloat(result[1]);
911
- const z = Number.parseFloat(result[2]);
912
- if (isNaN(x) || isNaN(y) || isNaN(z))
913
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 3D value was expected.`);
914
- return { x, y, z };
915
- }
916
- isSchemaFullNameValidForVersion(schemaFullName, ecXmlVersion) {
917
- const schemaNameParts = schemaFullName.split(".");
918
- if ((ecXmlVersion.readVersion >= 3 && ecXmlVersion.writeVersion >= 2) || ecXmlVersion.readVersion > 3) {
919
- if (schemaNameParts.length < 4)
920
- return false;
921
- }
922
- else {
923
- if (schemaNameParts.length < 3)
924
- return false;
925
- }
926
- return true;
927
- }
928
- parseXmlNamespace(xmlNamespace) {
929
- const regEx = new RegExp(`^${ECXML_URI}\\.([0-9]+)\\.([0-9]+)$`);
930
- const match = xmlNamespace.match(regEx);
931
- if (!match)
932
- return;
933
- const readVersion = parseInt(match[1], 10);
934
- const writeVersion = parseInt(match[2], 10);
935
- return { readVersion, writeVersion };
936
- }
937
- getQualifiedTypeName(rawTypeName) {
938
- const nameParts = rawTypeName.split(":");
939
- if (nameParts.length !== 2)
940
- return `${this._schemaName}.${rawTypeName}`;
941
- if (nameParts[0].toLowerCase() === this._schemaAlias.toLowerCase())
942
- return `${this._schemaName}.${nameParts[1]}`;
943
- if (this._schemaReferenceNames.has(nameParts[0].toLowerCase()))
944
- return `${this._schemaReferenceNames.get(nameParts[0].toLowerCase())}.${nameParts[1]}`;
945
- throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `No valid schema found for alias ${nameParts[0]}`);
946
- }
947
- /** The rest of the API uses the full name format of `{SchemaName}.{SchemaItemName}`,
948
- * meaning all of the references in the format string need to be changed.
949
- */
950
- getQualifiedPresentationUnits(presentationUnits) {
951
- const res = [];
952
- for (const presentationUnit of presentationUnits) {
953
- // we split the presentation unit by square parantheses [ ], f:DefaultReal(6)[u:FT|feet] will be splitted into f:DefaultReal(6) and u:FT|feet
954
- // we format the first one and the next one will be put into [ ] again
955
- const presentationUnitFormats = presentationUnit.split(/[\[\]]/g);
956
- let qualifiedPresentation = "";
957
- qualifiedPresentation = this.getQualifiedTypeName(presentationUnitFormats[0]);
958
- if (presentationUnitFormats.length > 1) {
959
- for (let i = 1; i < presentationUnitFormats.length; ++i) {
960
- if (presentationUnitFormats[i].length === 0)
961
- continue;
962
- const verticalSlashIdx = presentationUnitFormats[i].indexOf("|");
963
- const overrideFormat = this.getQualifiedTypeName(presentationUnitFormats[i].slice(0, verticalSlashIdx));
964
- const formatLabel = presentationUnitFormats[i].slice(verticalSlashIdx);
965
- qualifiedPresentation += `[${overrideFormat}${formatLabel}]`;
966
- }
967
- }
968
- res.push(qualifiedPresentation);
969
- }
970
- return res;
971
- }
972
- }
973
- exports.XmlParser = XmlParser;
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.XmlParser = void 0;
8
+ const core_bentley_1 = require("@itwin/core-bentley");
9
+ const ECObjects_1 = require("../ECObjects");
10
+ const Exception_1 = require("../Exception");
11
+ const ECName_1 = require("../ECName");
12
+ const AbstractParser_1 = require("./AbstractParser");
13
+ const NON_ITEM_SCHEMA_ELEMENTS = ["ECSchemaReference", "ECCustomAttributes"];
14
+ const ECXML_URI = "http://www\\.bentley\\.com/schemas/Bentley\\.ECXML";
15
+ /** @internal */
16
+ class XmlParser extends AbstractParser_1.AbstractParser {
17
+ constructor(rawSchema) {
18
+ super();
19
+ this._rawSchema = rawSchema;
20
+ const schemaInfo = rawSchema.documentElement;
21
+ const schemaName = schemaInfo.getAttribute("schemaName");
22
+ if (schemaName)
23
+ this._schemaName = schemaName;
24
+ this._schemaAlias = "";
25
+ const schemaAlias = schemaInfo.getAttribute("alias");
26
+ if (schemaAlias)
27
+ this._schemaAlias = schemaAlias;
28
+ this._schemaReferenceNames = new Map();
29
+ const schemaVersion = schemaInfo.getAttribute("version");
30
+ if (schemaVersion)
31
+ this._schemaVersion = schemaVersion;
32
+ const xmlNamespace = schemaInfo.getAttribute("xmlns");
33
+ if (xmlNamespace) {
34
+ this._xmlNamespace = xmlNamespace;
35
+ this._ecXmlVersion = this.parseXmlNamespace(this._xmlNamespace);
36
+ }
37
+ this._schemaItems = new Map();
38
+ this._mapIsPopulated = false;
39
+ }
40
+ parseSchema() {
41
+ const schemaMetadata = this._rawSchema.documentElement;
42
+ if ("ECSchema" !== schemaMetadata.nodeName)
43
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, "An ECSchema is missing the required metadata.");
44
+ const schemaDefDuplicates = this.getElementChildrenByTagName(schemaMetadata, "ECSchema");
45
+ if (schemaDefDuplicates.length > 1)
46
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, "An ECSchema has more than one ECSchema definition. Only one is allowed.");
47
+ if (this._schemaName === undefined)
48
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `An ECSchema is missing a required 'schemaName' attribute`);
49
+ if (this._schemaVersion === undefined)
50
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECSchema ${this._schemaName} is missing a required 'version' attribute`);
51
+ if (this._xmlNamespace === undefined)
52
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECSchema ${this._schemaName} is missing a required 'xmlns' attribute`);
53
+ if (this._ecXmlVersion === undefined)
54
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECSchema ${this._schemaName} has an invalid 'xmlns' attribute`);
55
+ const alias = this.getRequiredAttribute(schemaMetadata, "alias", `The ECSchema ${this._schemaName} is missing a required 'alias' attribute`);
56
+ const description = this.getOptionalAttribute(schemaMetadata, "description");
57
+ const displayLabel = this.getOptionalAttribute(schemaMetadata, "displayLabel");
58
+ const schemaProps = {
59
+ name: this._schemaName,
60
+ $schema: this._xmlNamespace,
61
+ version: this._schemaVersion,
62
+ alias,
63
+ label: displayLabel,
64
+ description,
65
+ };
66
+ return schemaProps;
67
+ }
68
+ *getReferences() {
69
+ const schemaReferences = this.getElementChildrenByTagName(this._rawSchema.documentElement, "ECSchemaReference");
70
+ for (const ref of schemaReferences) {
71
+ yield this.getSchemaReference(ref);
72
+ }
73
+ }
74
+ *getItems() {
75
+ if (!this._mapIsPopulated) {
76
+ const schemaItems = this.getSchemaChildren();
77
+ for (const item of schemaItems) {
78
+ let rawItemType = item.nodeName;
79
+ if (NON_ITEM_SCHEMA_ELEMENTS.includes(rawItemType))
80
+ continue;
81
+ // Differentiate a Mixin from an EntityClass
82
+ const customAttributesResult = this.getElementChildrenByTagName(item, "ECCustomAttributes");
83
+ if (customAttributesResult.length > 0) {
84
+ const customAttributes = customAttributesResult[0];
85
+ const isMixinResult = this.getElementChildrenByTagName(customAttributes, "IsMixin");
86
+ if (isMixinResult.length > 0)
87
+ rawItemType = "Mixin";
88
+ }
89
+ const itemType = this.getSchemaItemType(rawItemType);
90
+ if (itemType === undefined)
91
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `A SchemaItem in ${this._schemaName} has an invalid type. '${rawItemType}' is not a valid SchemaItem type.`);
92
+ const itemName = this.getRequiredAttribute(item, "typeName", `A SchemaItem in ${this._schemaName} is missing the required 'typeName' attribute.`);
93
+ if (!ECName_1.ECName.validate(itemName))
94
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidECName, `A SchemaItem in ${this._schemaName} has an invalid 'typeName' attribute. '${itemName}' is not a valid ECName.`);
95
+ this._currentItemFullName = `${this._schemaName}.${itemName}`;
96
+ this._schemaItems.set(itemName, [itemType, item]);
97
+ yield [itemName, itemType, item];
98
+ }
99
+ this._mapIsPopulated = true;
100
+ }
101
+ else {
102
+ for (const [itemName, [itemType, item]] of this._schemaItems) {
103
+ this._currentItemFullName = `${this._schemaName}.${itemName}`;
104
+ yield [itemName, itemType, item];
105
+ }
106
+ }
107
+ }
108
+ findItem(itemName) {
109
+ if (!this._mapIsPopulated) {
110
+ for (const item of this.getItems()) {
111
+ if (item[0] === itemName) {
112
+ this._currentItemFullName = `${this._schemaName}.${itemName}`;
113
+ return item;
114
+ }
115
+ }
116
+ }
117
+ else {
118
+ const values = this._schemaItems.get(itemName);
119
+ if (undefined !== values) {
120
+ const [itemType, item] = values;
121
+ this._currentItemFullName = `${this._schemaName}.${itemName}`;
122
+ return [itemName, itemType, item];
123
+ }
124
+ }
125
+ return undefined;
126
+ }
127
+ parseEntityClass(xmlElement) {
128
+ const classProps = this.getClassProps(xmlElement);
129
+ const baseClasses = this.getElementChildrenByTagName(xmlElement, "BaseClass");
130
+ let mixinElements;
131
+ const mixins = new Array();
132
+ // if it has just one BaseClass we assume it is a 'true' base class not a mixin
133
+ if (baseClasses.length > 1) {
134
+ mixinElements = baseClasses.slice(1);
135
+ for (const mixin of mixinElements) {
136
+ if (mixin.textContent) {
137
+ const typeName = this.getQualifiedTypeName(mixin.textContent);
138
+ mixins.push(typeName);
139
+ }
140
+ }
141
+ }
142
+ const entityClassProps = {
143
+ ...classProps,
144
+ mixins,
145
+ };
146
+ return entityClassProps;
147
+ }
148
+ parseMixin(xmlElement) {
149
+ const classProps = this.getClassProps(xmlElement);
150
+ const baseClasses = this.getElementChildrenByTagName(xmlElement, "BaseClass");
151
+ // Mixins can only have one base class
152
+ if (baseClasses.length > 1)
153
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} has more than one base class which is not allowed.`);
154
+ const customAttributesResult = this.getElementChildrenByTagName(xmlElement, "ECCustomAttributes");
155
+ if (customAttributesResult.length < 1)
156
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'IsMixin' tag.`);
157
+ const customAttributes = customAttributesResult[0];
158
+ const isMixinResult = this.getElementChildrenByTagName(customAttributes, "IsMixin");
159
+ if (isMixinResult.length < 1)
160
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'IsMixin' tag.`);
161
+ const mixinAttributes = isMixinResult[0];
162
+ const appliesToResult = this.getElementChildrenByTagName(mixinAttributes, "AppliesToEntityClass");
163
+ if (appliesToResult.length < 1)
164
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'AppliesToEntityClass' tag.`);
165
+ const appliesToElement = appliesToResult[0];
166
+ let appliesTo = appliesToElement.textContent;
167
+ if (appliesTo === null || appliesTo.length === 0)
168
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Mixin ${this._currentItemFullName} is missing the required 'AppliesToEntityClass' tag.`);
169
+ appliesTo = this.getQualifiedTypeName(appliesTo);
170
+ const mixinProps = {
171
+ ...classProps,
172
+ appliesTo,
173
+ };
174
+ return mixinProps;
175
+ }
176
+ parseStructClass(xmlElement) {
177
+ return this.getClassProps(xmlElement);
178
+ }
179
+ parseCustomAttributeClass(xmlElement) {
180
+ const classProps = this.getClassProps(xmlElement);
181
+ const appliesTo = this.getRequiredAttribute(xmlElement, "appliesTo", `The CustomAttributeClass ${this._currentItemFullName} is missing the required 'appliesTo' attribute.`);
182
+ const customAttributeClassProps = {
183
+ ...classProps,
184
+ appliesTo,
185
+ };
186
+ return customAttributeClassProps;
187
+ }
188
+ parseRelationshipClass(xmlElement) {
189
+ const classProps = this.getClassProps(xmlElement);
190
+ const strength = this.getRequiredAttribute(xmlElement, "strength", `The RelationshipClass ${this._currentItemFullName} is missing the required 'strength' attribute.`);
191
+ let strengthDirection = this.getOptionalAttribute(xmlElement, "strengthDirection");
192
+ if (!strengthDirection)
193
+ strengthDirection = (0, ECObjects_1.strengthDirectionToString)(ECObjects_1.StrengthDirection.Forward);
194
+ const sourceResult = this.getElementChildrenByTagName(xmlElement, "Source");
195
+ if (sourceResult.length !== 1) {
196
+ if (sourceResult.length === 0)
197
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Source constraint tag.`);
198
+ else
199
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} has more than one Source constraint tag. Only one is allowed.`);
200
+ }
201
+ const source = this.getRelationshipConstraintProps(sourceResult[0], true);
202
+ const targetResult = this.getElementChildrenByTagName(xmlElement, "Target");
203
+ if (targetResult.length !== 1) {
204
+ if (targetResult.length === 0)
205
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Target constraint tag.`);
206
+ else
207
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} has more than one Target constraint tag. Only one is allowed.`);
208
+ }
209
+ const target = this.getRelationshipConstraintProps(targetResult[0], false);
210
+ return {
211
+ ...classProps,
212
+ strength,
213
+ strengthDirection,
214
+ source,
215
+ target,
216
+ };
217
+ }
218
+ parseEnumeration(xmlElement) {
219
+ const itemProps = this.getSchemaItemProps(xmlElement);
220
+ const enumType = this.getRequiredAttribute(xmlElement, "backingTypeName", `The Enumeration ${this._currentItemFullName} is missing the required 'backingTypeName' attribute.`);
221
+ // TODO: This shouldn't be verified here. It's for the deserialize method to handle. The only reason it's currently done here so that the xml
222
+ // value can be put in the correct type, number or string.
223
+ let tempBackingType;
224
+ if (/int/i.test(enumType))
225
+ tempBackingType = ECObjects_1.PrimitiveType.Integer;
226
+ else if (/string/i.test(enumType))
227
+ tempBackingType = ECObjects_1.PrimitiveType.String;
228
+ else
229
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidECJson, `The Enumeration ${this._currentItemFullName} has an invalid 'backingTypeName' attribute. It should be either "int" or "string".`);
230
+ let isStrictString = this.getOptionalAttribute(xmlElement, "isStrict");
231
+ if (isStrictString === undefined)
232
+ isStrictString = "true";
233
+ const isStrict = this.parseBoolean(isStrictString, `The Enumeration ${this._currentItemFullName} has an invalid 'isStrict' attribute. It should either be "true" or "false".`);
234
+ const enumeratorElements = this.getElementChildrenByTagName(xmlElement, "ECEnumerator");
235
+ const enumerators = new Array();
236
+ for (const element of enumeratorElements) {
237
+ const name = this.getRequiredAttribute(element, "name", `The Enumeration ${this._currentItemFullName} has an enumerator that is missing the required attribute 'name'.`);
238
+ const valueString = this.getRequiredAttribute(element, "value", `The Enumeration ${this._currentItemFullName} has an enumerator that is missing the required attribute 'value'.`);
239
+ let value = valueString;
240
+ if (ECObjects_1.PrimitiveType.Integer === tempBackingType) {
241
+ const numericValue = parseInt(valueString, 10);
242
+ if (isNaN(numericValue))
243
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Enumeration ${this._currentItemFullName} of type "int" has an enumerator with a non-integer value.`);
244
+ value = numericValue;
245
+ }
246
+ const label = this.getOptionalAttribute(element, "displayLabel");
247
+ const description = this.getOptionalAttribute(element, "description");
248
+ enumerators.push({
249
+ name,
250
+ value,
251
+ label,
252
+ description,
253
+ });
254
+ }
255
+ return {
256
+ ...itemProps,
257
+ type: enumType,
258
+ isStrict,
259
+ enumerators,
260
+ };
261
+ }
262
+ parseKindOfQuantity(xmlElement) {
263
+ const itemProps = this.getSchemaItemProps(xmlElement);
264
+ const relativeErrorString = this.getRequiredAttribute(xmlElement, "relativeError", `The KindOfQuantity ${this._currentItemFullName} is missing the required 'relativeError' attribute.`);
265
+ const relativeError = parseFloat(relativeErrorString);
266
+ if (isNaN(relativeError))
267
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The KindOfQuantity ${this._currentItemFullName} has an invalid 'relativeError' attribute. It should be a numeric value.`);
268
+ const presentationUnitsString = this.getOptionalAttribute(xmlElement, "presentationUnits");
269
+ let presentationUnits;
270
+ if (presentationUnitsString)
271
+ presentationUnits = this.getQualifiedPresentationUnits(presentationUnitsString.split(";"));
272
+ let persistenceUnit = this.getRequiredAttribute(xmlElement, "persistenceUnit", `The KindOfQuantity ${this._currentItemFullName} is missing the required 'persistenceUnit' attribute.`);
273
+ persistenceUnit = this.getQualifiedTypeName(persistenceUnit);
274
+ return {
275
+ ...itemProps,
276
+ relativeError,
277
+ presentationUnits,
278
+ persistenceUnit,
279
+ };
280
+ }
281
+ parsePropertyCategory(xmlElement) {
282
+ const itemProps = this.getSchemaItemProps(xmlElement);
283
+ const priorityString = this.getRequiredAttribute(xmlElement, "priority", `The PropertyCategory ${this._currentItemFullName} is missing the required 'priority' attribute.`);
284
+ const priority = parseInt(priorityString, 10);
285
+ if (isNaN(priority))
286
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The PropertyCategory ${this._currentItemFullName} has an invalid 'priority' attribute. It should be a numeric value.`);
287
+ return {
288
+ ...itemProps,
289
+ priority,
290
+ };
291
+ }
292
+ parseUnit(xmlElement) {
293
+ const itemProps = this.getSchemaItemProps(xmlElement);
294
+ let phenomenon = this.getRequiredAttribute(xmlElement, "phenomenon", `The Unit ${this._currentItemFullName} is missing the required 'phenomenon' attribute.`);
295
+ let unitSystem = this.getRequiredAttribute(xmlElement, "unitSystem", `The Unit ${this._currentItemFullName} is missing the required 'unitSystem' attribute.`);
296
+ const definition = this.getRequiredAttribute(xmlElement, "definition", `The Unit ${this._currentItemFullName} is missing the required 'definition' attribute.`);
297
+ const numerator = this.getOptionalFloatAttribute(xmlElement, "numerator", `The Unit ${this._currentItemFullName} has an invalid 'numerator' attribute. It should be a numeric value.`);
298
+ const denominator = this.getOptionalFloatAttribute(xmlElement, "denominator", `The Unit ${this._currentItemFullName} has an invalid 'denominator' attribute. It should be a numeric value.`);
299
+ const offset = this.getOptionalFloatAttribute(xmlElement, "offset", `The Unit ${this._currentItemFullName} has an invalid 'offset' attribute. It should be a numeric value.`);
300
+ phenomenon = this.getQualifiedTypeName(phenomenon);
301
+ unitSystem = this.getQualifiedTypeName(unitSystem);
302
+ return {
303
+ ...itemProps,
304
+ phenomenon,
305
+ unitSystem,
306
+ definition,
307
+ numerator,
308
+ denominator,
309
+ offset,
310
+ };
311
+ }
312
+ parseInvertedUnit(xmlElement) {
313
+ const itemProps = this.getSchemaItemProps(xmlElement);
314
+ let invertsUnit = this.getRequiredAttribute(xmlElement, "invertsUnit", `The InvertedUnit ${this._currentItemFullName} is missing the required 'invertsUnit' attribute.`);
315
+ let unitSystem = this.getRequiredAttribute(xmlElement, "unitSystem", `The InvertedUnit ${this._currentItemFullName} is missing the required 'unitSystem' attribute.`);
316
+ invertsUnit = this.getQualifiedTypeName(invertsUnit);
317
+ unitSystem = this.getQualifiedTypeName(unitSystem);
318
+ return {
319
+ ...itemProps,
320
+ invertsUnit,
321
+ unitSystem,
322
+ };
323
+ }
324
+ parseConstant(xmlElement) {
325
+ const itemProps = this.getSchemaItemProps(xmlElement);
326
+ let phenomenon = this.getRequiredAttribute(xmlElement, "phenomenon", `The Constant ${this._currentItemFullName} is missing the required 'phenomenon' attribute.`);
327
+ const definition = this.getRequiredAttribute(xmlElement, "definition", `The Constant ${this._currentItemFullName} is missing the required 'definition' attribute.`);
328
+ const numerator = this.getOptionalFloatAttribute(xmlElement, "numerator", `The Constant ${this._currentItemFullName} has an invalid 'numerator' attribute. It should be a numeric value.`);
329
+ const denominator = this.getOptionalFloatAttribute(xmlElement, "denominator", `The Constant ${this._currentItemFullName} has an invalid 'denominator' attribute. It should be a numeric value.`);
330
+ phenomenon = this.getQualifiedTypeName(phenomenon);
331
+ return {
332
+ ...itemProps,
333
+ phenomenon,
334
+ definition,
335
+ numerator,
336
+ denominator,
337
+ };
338
+ }
339
+ parsePhenomenon(xmlElement) {
340
+ const itemProps = this.getSchemaItemProps(xmlElement);
341
+ const definition = this.getRequiredAttribute(xmlElement, "definition", `The Phenomenon ${this._currentItemFullName} is missing the required 'definition' attribute.`);
342
+ return {
343
+ ...itemProps,
344
+ definition,
345
+ };
346
+ }
347
+ parseFormat(xmlElement) {
348
+ const itemProps = this.getSchemaItemProps(xmlElement);
349
+ const formatType = this.getRequiredAttribute(xmlElement, "type", `The Format ${this._currentItemFullName} is missing the required 'type' attribute.`);
350
+ const precision = this.getOptionalIntAttribute(xmlElement, "precision", `The Format ${this._currentItemFullName} has an invalid 'precision' attribute. It should be a numeric value.`);
351
+ const roundFactor = this.getOptionalFloatAttribute(xmlElement, "roundFactor", `The Format ${this._currentItemFullName} has an invalid 'roundFactor' attribute. It should be a numeric value.`);
352
+ const minWidth = this.getOptionalIntAttribute(xmlElement, "minWidth", `The Format ${this._currentItemFullName} has an invalid 'minWidth' attribute. It should be a numeric value.`);
353
+ const showSignOption = this.getOptionalAttribute(xmlElement, "showSignOption");
354
+ const formatTraitsString = this.getRequiredAttribute(xmlElement, "formatTraits", `The Format ${this._currentItemFullName} is missing the required 'formatTraits' attribute.`);
355
+ const formatTraits = formatTraitsString.split("|");
356
+ const decimalSeparator = this.getOptionalAttribute(xmlElement, "decimalSeparator");
357
+ const thousandSeparator = this.getOptionalAttribute(xmlElement, "thousandSeparator");
358
+ const uomSeparator = this.getOptionalAttribute(xmlElement, "uomSeparator");
359
+ const scientificType = this.getOptionalAttribute(xmlElement, "scientificType");
360
+ const stationOffsetSize = this.getOptionalIntAttribute(xmlElement, "stationOffsetSize", `The Format ${this._currentItemFullName} has an invalid 'stationOffsetSize' attribute. It should be a numeric value.`);
361
+ const stationSeparator = this.getOptionalAttribute(xmlElement, "stationSeparator");
362
+ let composite;
363
+ const compositeResult = this.getElementChildrenByTagName(xmlElement, "Composite");
364
+ if (compositeResult.length > 0) {
365
+ const compositeElement = compositeResult[0];
366
+ const spacer = this.getOptionalAttribute(compositeElement, "spacer");
367
+ const includeZeroString = this.getOptionalAttribute(compositeElement, "includeZero");
368
+ let includeZero;
369
+ if (includeZeroString) {
370
+ includeZero = this.parseBoolean(includeZeroString, `The Format ${this._currentItemFullName} has a Composite with an invalid 'includeZero' attribute. It should be either "true" or "false".`);
371
+ }
372
+ const units = new Array();
373
+ const unitsResult = this.getElementChildrenByTagName(compositeElement, "Unit");
374
+ if (unitsResult.length < 1)
375
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Format ${this._currentItemFullName} has an invalid 'Composite' element. It should have 1-4 Unit elements.`);
376
+ for (const unit of unitsResult) {
377
+ let name = unit.textContent;
378
+ if (null === name || 0 === name.length)
379
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The Format ${this._currentItemFullName} has a Composite with an invalid Unit. One of the Units is missing the required 'name' attribute.`);
380
+ const label = this.getOptionalAttribute(unit, "label");
381
+ name = this.getQualifiedTypeName(name);
382
+ units.push({ name, label });
383
+ }
384
+ composite = {
385
+ spacer,
386
+ includeZero,
387
+ units,
388
+ };
389
+ }
390
+ return {
391
+ ...itemProps,
392
+ type: formatType,
393
+ precision,
394
+ roundFactor,
395
+ minWidth,
396
+ showSignOption,
397
+ formatTraits,
398
+ decimalSeparator,
399
+ thousandSeparator,
400
+ uomSeparator,
401
+ scientificType,
402
+ stationOffsetSize,
403
+ stationSeparator,
404
+ composite,
405
+ };
406
+ }
407
+ parseUnitSystem(xmlElement) {
408
+ return this.getClassProps(xmlElement);
409
+ }
410
+ *getProperties(xmlElement, itemName) {
411
+ const propertyTagRegex = /EC((Struct(Array)?)|Array|Navigation)?Property/;
412
+ const children = this.getElementChildrenByTagName(xmlElement, propertyTagRegex);
413
+ for (const child of children) {
414
+ const childType = child.nodeName;
415
+ const propertyName = this.getRequiredAttribute(child, "propertyName", `An ECProperty in ${itemName} is missing the required 'propertyName' attribute.`);
416
+ const propertyType = this.getPropertyType(childType);
417
+ // This may not be needed, just a failsafe if the regex is faulty
418
+ if (propertyType === undefined)
419
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECProperty ${itemName}.${propertyName} has an invalid type. ${childType} is not a valid ECProperty type.`);
420
+ yield [propertyName, propertyType, child];
421
+ }
422
+ }
423
+ parsePrimitiveProperty(xmlElement) {
424
+ const propertyProps = this.getPrimitiveOrEnumPropertyBaseProps(xmlElement);
425
+ const typeName = this.getPropertyTypeName(xmlElement);
426
+ const primitivePropertyProps = { ...propertyProps, typeName };
427
+ return primitivePropertyProps;
428
+ }
429
+ parseStructProperty(xmlElement) {
430
+ const propertyProps = this.getPropertyProps(xmlElement);
431
+ const typeName = this.getPropertyTypeName(xmlElement);
432
+ const structPropertyProps = { ...propertyProps, typeName };
433
+ return structPropertyProps;
434
+ }
435
+ parsePrimitiveArrayProperty(xmlElement) {
436
+ const typeName = this.getPropertyTypeName(xmlElement);
437
+ const propertyProps = this.getPrimitiveOrEnumPropertyBaseProps(xmlElement);
438
+ const minAndMaxOccurs = this.getPropertyMinAndMaxOccurs(xmlElement);
439
+ return {
440
+ ...propertyProps,
441
+ ...minAndMaxOccurs,
442
+ typeName,
443
+ };
444
+ }
445
+ parseStructArrayProperty(xmlElement) {
446
+ const propertyProps = this.getPropertyProps(xmlElement);
447
+ const typeName = this.getPropertyTypeName(xmlElement);
448
+ const minAndMaxOccurs = this.getPropertyMinAndMaxOccurs(xmlElement);
449
+ return {
450
+ ...propertyProps,
451
+ ...minAndMaxOccurs,
452
+ typeName,
453
+ };
454
+ }
455
+ parseNavigationProperty(xmlElement) {
456
+ const propName = this.getPropertyName(xmlElement);
457
+ const propertyProps = this.getPropertyProps(xmlElement);
458
+ let relationshipName = this.getRequiredAttribute(xmlElement, "relationshipName", `The ECNavigationProperty ${this._currentItemFullName}.${propName} is missing the required 'relationshipName' property.`);
459
+ const direction = this.getRequiredAttribute(xmlElement, "direction", `The ECNavigationProperty ${this._currentItemFullName}.${propName} is missing the required 'direction' property.`);
460
+ relationshipName = this.getQualifiedTypeName(relationshipName);
461
+ return {
462
+ ...propertyProps,
463
+ relationshipName,
464
+ direction,
465
+ };
466
+ }
467
+ getSchemaCustomAttributeProviders() {
468
+ return this.getCustomAttributeProviders(this._rawSchema.documentElement, "Schema", this._schemaName);
469
+ }
470
+ getClassCustomAttributeProviders(xmlElement) {
471
+ return this.getCustomAttributeProviders(xmlElement, "ECClass", this._currentItemFullName);
472
+ }
473
+ getPropertyCustomAttributeProviders(xmlElement) {
474
+ const propName = this.getPropertyName(xmlElement);
475
+ return this.getCustomAttributeProviders(xmlElement, "ECProperty", `${this._currentItemFullName}.${propName}`);
476
+ }
477
+ getRelationshipConstraintCustomAttributeProviders(xmlElement) {
478
+ const sourceResult = this.getElementChildrenByTagName(xmlElement, "Source");
479
+ if (sourceResult.length < 1)
480
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Source constraint tag.`);
481
+ const sourceElement = sourceResult[0];
482
+ const sourceCustomAttributes = this.getCustomAttributeProviders(sourceElement, "Source Constraint of", this._currentItemFullName);
483
+ const targetResult = this.getElementChildrenByTagName(xmlElement, "Target");
484
+ if (targetResult.length < 1)
485
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The RelationshipClass ${this._currentItemFullName} is missing the required Target constraint tag.`);
486
+ const targetElement = targetResult[0];
487
+ const targetCustomAttributes = this.getCustomAttributeProviders(targetElement, "Source Constraint of", this._currentItemFullName);
488
+ return [sourceCustomAttributes, targetCustomAttributes];
489
+ }
490
+ getElementChildren(xmlElement) {
491
+ // NodeListOf<T> does not define [Symbol.iterator]
492
+ const children = Array.from(xmlElement.childNodes).filter((child) => {
493
+ // (node.nodeType === 1) implies instanceof Element
494
+ // https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/children#Polyfill
495
+ return child.nodeType === 1;
496
+ });
497
+ return children;
498
+ }
499
+ getElementChildrenByTagName(xmlElement, tagName) {
500
+ const children = this.getElementChildren(xmlElement);
501
+ if ("*" === tagName)
502
+ return children;
503
+ let result;
504
+ if (typeof tagName === "string") {
505
+ result = children.filter((child) => {
506
+ return tagName.toLowerCase() === child.nodeName.toLowerCase();
507
+ });
508
+ }
509
+ else {
510
+ result = children.filter((child) => {
511
+ return tagName.test(child.nodeName);
512
+ });
513
+ }
514
+ return result;
515
+ }
516
+ getOptionalAttribute(xmlElement, attributeName) {
517
+ if (!xmlElement.hasAttribute(attributeName))
518
+ return undefined;
519
+ const result = xmlElement.getAttribute(attributeName);
520
+ // The typings for the return value of getAttribute do not match that of xmldom
521
+ // xmldom returns an empty string instead of null
522
+ // However Typescript will still treat result as a union type without this check
523
+ // Hence this is needed for tsc to compile
524
+ if (result === null)
525
+ return undefined;
526
+ return result;
527
+ }
528
+ getOptionalFloatAttribute(xmlElement, attributeName, parseErrorMsg) {
529
+ const resultString = this.getOptionalAttribute(xmlElement, attributeName);
530
+ let result;
531
+ if (resultString) {
532
+ result = parseFloat(resultString);
533
+ if (isNaN(result))
534
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, parseErrorMsg);
535
+ }
536
+ return result;
537
+ }
538
+ getOptionalIntAttribute(xmlElement, attributeName, parseErrorMsg) {
539
+ const resultString = this.getOptionalAttribute(xmlElement, attributeName);
540
+ let result;
541
+ if (resultString) {
542
+ result = parseInt(resultString, 10);
543
+ if (isNaN(result))
544
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, parseErrorMsg);
545
+ }
546
+ return result;
547
+ }
548
+ parseBoolean(text, parseErrorMsg) {
549
+ const textString = text.toLowerCase();
550
+ if ("true" === textString)
551
+ return true;
552
+ else if ("false" === textString)
553
+ return false;
554
+ else
555
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, parseErrorMsg);
556
+ }
557
+ getRequiredAttribute(xmlElement, attributeName, errorMsg) {
558
+ if (!xmlElement.hasAttribute(attributeName))
559
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, errorMsg);
560
+ const result = xmlElement.getAttribute(attributeName);
561
+ if (result === null)
562
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, errorMsg);
563
+ return result;
564
+ }
565
+ getSchemaReference(xmlElement) {
566
+ const alias = this.getRequiredAttribute(xmlElement, "alias", `The schema ${this._schemaName} has an invalid ECSchemaReference attribute. One of the references is missing the required 'alias' attribute.`);
567
+ const name = this.getRequiredAttribute(xmlElement, "name", `The schema ${this._schemaName} has an invalid ECSchemaReference attribute. One of the references is missing the required 'name' attribute.`);
568
+ const version = this.getRequiredAttribute(xmlElement, "version", `The schema ${this._schemaName} has an invalid ECSchemaReference attribute. One of the references is missing the required 'version' attribute.`);
569
+ if (!this._schemaReferenceNames.has(alias.toLowerCase()))
570
+ this._schemaReferenceNames.set(alias.toLowerCase(), name);
571
+ return {
572
+ name,
573
+ version,
574
+ };
575
+ }
576
+ getSchemaItemType(rawType) {
577
+ switch (rawType.toLowerCase()) {
578
+ case "ecentityclass": return "EntityClass";
579
+ case "mixin": return "Mixin";
580
+ case "ecstructclass": return "StructClass";
581
+ case "eccustomattributeclass": return "CustomAttributeClass";
582
+ case "ecrelationshipclass": return "RelationshipClass";
583
+ case "ecenumeration": return "Enumeration";
584
+ case "kindofquantity": return "KindOfQuantity";
585
+ case "propertycategory": return "PropertyCategory";
586
+ case "unit": return "Unit";
587
+ case "invertedunit": return "InvertedUnit";
588
+ case "constant": return "Constant";
589
+ case "phenomenon": return "Phenomenon";
590
+ case "unitsystem": return "UnitSystem";
591
+ case "format": return "Format";
592
+ }
593
+ return undefined;
594
+ }
595
+ getSchemaChildren() {
596
+ const schemaMetadata = this._rawSchema.documentElement;
597
+ return this.getElementChildren(schemaMetadata);
598
+ }
599
+ getSchemaItemProps(xmlElement) {
600
+ const displayLabel = this.getOptionalAttribute(xmlElement, "displayLabel");
601
+ const description = this.getOptionalAttribute(xmlElement, "description");
602
+ return {
603
+ description,
604
+ label: displayLabel,
605
+ };
606
+ }
607
+ getClassProps(xmlElement) {
608
+ const itemProps = this.getSchemaItemProps(xmlElement);
609
+ const modifier = this.getOptionalAttribute(xmlElement, "modifier");
610
+ let baseClass = null;
611
+ const baseClasses = this.getElementChildrenByTagName(xmlElement, "BaseClass");
612
+ if (baseClasses.length > 0) {
613
+ // We are assuming here that the first BaseClass is the 'real' one - the rest are mixins
614
+ // This is not a finalized approach as this could lead to unsupported schemas
615
+ baseClass = baseClasses[0].textContent;
616
+ }
617
+ baseClass = baseClass ? this.getQualifiedTypeName(baseClass) : undefined;
618
+ return {
619
+ ...itemProps,
620
+ modifier,
621
+ baseClass,
622
+ };
623
+ }
624
+ getRelationshipConstraintProps(xmlElement, isSource) {
625
+ const constraintName = `${(isSource) ? "Source" : "Target"} Constraint of ${this._currentItemFullName}`;
626
+ const multiplicity = this.getRequiredAttribute(xmlElement, "multiplicity", `The ${constraintName} is missing the required 'multiplicity' attribute.`);
627
+ const roleLabel = this.getRequiredAttribute(xmlElement, "roleLabel", `The ${constraintName} is missing the required 'roleLabel' attribute.`);
628
+ const polymorphicString = this.getRequiredAttribute(xmlElement, "polymorphic", `The ${constraintName} is missing the required 'polymorphic' attribute.`);
629
+ const polymorphic = this.parseBoolean(polymorphicString, `The ${constraintName} has an invalid 'polymorphic' attribute. It should either be "true" or "false".`);
630
+ let abstractConstraint = this.getOptionalAttribute(xmlElement, "abstractConstraint");
631
+ if (undefined !== abstractConstraint)
632
+ abstractConstraint = this.getQualifiedTypeName(abstractConstraint);
633
+ const constraintClasses = new Array();
634
+ const constraintClassesResult = this.getElementChildrenByTagName(xmlElement, "Class");
635
+ if (constraintClassesResult.length < 1)
636
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ${constraintName} is missing the required Class tags.`);
637
+ for (const constraintClass of constraintClassesResult) {
638
+ let constraintClassId = constraintClass.getAttribute("class");
639
+ if (null === constraintClassId || 0 === constraintClassId.length)
640
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ${constraintName} has a Class that is missing the required 'class' attribute.`);
641
+ constraintClassId = this.getQualifiedTypeName(constraintClassId);
642
+ constraintClasses.push(constraintClassId);
643
+ }
644
+ return {
645
+ multiplicity,
646
+ roleLabel,
647
+ polymorphic,
648
+ abstractConstraint,
649
+ constraintClasses,
650
+ };
651
+ }
652
+ getPropertyType(propType) {
653
+ switch (propType) {
654
+ case "ECNavigationProperty": return "navigationproperty";
655
+ case "ECStructProperty": return "structproperty";
656
+ case "ECArrayProperty": return "primitivearrayproperty";
657
+ case "ECStructArrayProperty": return "structarrayproperty";
658
+ case "ECProperty": return "primitiveproperty";
659
+ default: return undefined;
660
+ }
661
+ }
662
+ getPropertyName(xmlElement) {
663
+ return this.getRequiredAttribute(xmlElement, "propertyName", `An ECProperty in ${this._currentItemFullName} is missing the required 'propertyName' attribute.`);
664
+ }
665
+ getPropertyProps(xmlElement) {
666
+ const propName = this.getPropertyName(xmlElement);
667
+ const propType = this.getPropertyType(xmlElement.nodeName);
668
+ if (propType === undefined)
669
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid type. ${propType} is not a valid ECProperty type.`);
670
+ const label = this.getOptionalAttribute(xmlElement, "displayLabel");
671
+ const description = this.getOptionalAttribute(xmlElement, "description");
672
+ const readOnlyString = this.getOptionalAttribute(xmlElement, "readOnly");
673
+ let isReadOnly;
674
+ if (readOnlyString) {
675
+ isReadOnly = this.parseBoolean(readOnlyString, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'readOnly' attribute. It should be either "true" or "false".`);
676
+ }
677
+ let category = this.getOptionalAttribute(xmlElement, "category");
678
+ const priority = this.getOptionalIntAttribute(xmlElement, "priority", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'priority' attribute. It should be a numeric value.`);
679
+ const inheritedString = this.getOptionalAttribute(xmlElement, "inherited");
680
+ let inherited;
681
+ if (inheritedString) {
682
+ inherited = this.parseBoolean(inheritedString, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'inherited' attribute. It should be either "true" or "false".`);
683
+ }
684
+ let kindOfQuantity = this.getOptionalAttribute(xmlElement, "kindOfQuantity");
685
+ if (kindOfQuantity)
686
+ kindOfQuantity = this.getQualifiedTypeName(kindOfQuantity);
687
+ if (category)
688
+ category = this.getQualifiedTypeName(category);
689
+ return {
690
+ name: propName,
691
+ type: propType,
692
+ description,
693
+ label,
694
+ isReadOnly,
695
+ category,
696
+ priority,
697
+ inherited,
698
+ kindOfQuantity,
699
+ };
700
+ }
701
+ getPropertyTypeName(xmlElement) {
702
+ const propName = this.getPropertyName(xmlElement);
703
+ const rawTypeName = this.getRequiredAttribute(xmlElement, "typeName", `The ECProperty ${this._currentItemFullName}.${propName} is missing the required 'typeName' attribute.`);
704
+ // If not a primitive type, we must prepend the schema name.
705
+ const primitiveType = (0, ECObjects_1.parsePrimitiveType)(rawTypeName);
706
+ if (primitiveType)
707
+ return rawTypeName;
708
+ return this.getQualifiedTypeName(rawTypeName);
709
+ }
710
+ getPrimitiveOrEnumPropertyBaseProps(xmlElement) {
711
+ const propertyProps = this.getPropertyProps(xmlElement);
712
+ const propName = propertyProps.name;
713
+ const extendedTypeName = this.getOptionalAttribute(xmlElement, "extendedTypeName");
714
+ const minLength = this.getOptionalIntAttribute(xmlElement, "minimumLength", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'minimumLength' attribute. It should be a numeric value.`);
715
+ const maxLength = this.getOptionalIntAttribute(xmlElement, "maximumLength", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'maximumLength' attribute. It should be a numeric value.`);
716
+ const minValue = this.getOptionalIntAttribute(xmlElement, "minimumValue", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'minimumValue' attribute. It should be a numeric value.`);
717
+ const maxValue = this.getOptionalIntAttribute(xmlElement, "maximumValue", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'maximumValue' attribute. It should be a numeric value.`);
718
+ return {
719
+ ...propertyProps,
720
+ extendedTypeName,
721
+ minLength,
722
+ maxLength,
723
+ minValue,
724
+ maxValue,
725
+ };
726
+ }
727
+ getPropertyMinAndMaxOccurs(xmlElement) {
728
+ const propName = this.getPropertyName(xmlElement);
729
+ const minOccurs = this.getOptionalIntAttribute(xmlElement, "minOccurs", `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'minOccurs' attribute. It should be a numeric value.`);
730
+ const maxOccursStr = this.getOptionalAttribute(xmlElement, "maxOccurs");
731
+ let maxOccurs;
732
+ if ("unbounded" === maxOccursStr)
733
+ maxOccurs = 2147483647; // TODO: This should be using the INT32_MAX variable.
734
+ else if (undefined !== maxOccursStr) {
735
+ maxOccurs = parseInt(maxOccursStr, 10);
736
+ if (isNaN(maxOccurs))
737
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `The ECProperty ${this._currentItemFullName}.${propName} has an invalid 'maxOccurs' attribute. It should be a numeric value.`);
738
+ }
739
+ return { minOccurs, maxOccurs };
740
+ }
741
+ *getCustomAttributeProviders(xmlElement, type, _name) {
742
+ const customAttributesResult = this.getElementChildrenByTagName(xmlElement, "ECCustomAttributes");
743
+ if (customAttributesResult.length < 1)
744
+ return;
745
+ const attributes = this.getElementChildren(customAttributesResult[0]);
746
+ for (const attribute of attributes) {
747
+ if ("ECClass" === type && "IsMixin" === attribute.tagName)
748
+ continue;
749
+ yield this.getCustomAttributeProvider(attribute);
750
+ }
751
+ }
752
+ getCustomAttributeProvider(xmlCustomAttribute) {
753
+ (0, core_bentley_1.assert)(this._ecXmlVersion !== undefined);
754
+ let ns = xmlCustomAttribute.getAttribute("xmlns");
755
+ if (!ns) {
756
+ (0, core_bentley_1.assert)(this._schemaName !== undefined);
757
+ (0, core_bentley_1.assert)(this._schemaVersion !== undefined);
758
+ ns = `${this._schemaName}.${this._schemaVersion}`;
759
+ }
760
+ if (null === ns || !this.isSchemaFullNameValidForVersion(ns, this._ecXmlVersion))
761
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Custom attribute namespaces must contain a valid 3.2 full schema name in the form <schemaName>.RR.ww.mm.`);
762
+ const schemaNameParts = ns.split(".");
763
+ const className = `${schemaNameParts[0]}.${xmlCustomAttribute.tagName}`;
764
+ const properties = this.getElementChildren(xmlCustomAttribute);
765
+ const provider = (caClass) => {
766
+ return this.addCAPropertyValues(caClass, properties);
767
+ };
768
+ return [className, provider];
769
+ }
770
+ addCAPropertyValues(caClass, propertyElements) {
771
+ const instance = { className: caClass.fullName };
772
+ if (!caClass.properties)
773
+ return instance;
774
+ for (const propertyElement of propertyElements) {
775
+ const value = this.readPropertyValue(propertyElement, caClass);
776
+ if (value !== undefined)
777
+ instance[propertyElement.tagName] = value;
778
+ }
779
+ return instance;
780
+ }
781
+ readPropertyValue(propElement, parentClass) {
782
+ const propertyClass = parentClass.getPropertySync(propElement.tagName);
783
+ if (!propertyClass)
784
+ return;
785
+ if (propertyClass.isArray())
786
+ return this.readArrayPropertyValue(propElement, propertyClass);
787
+ let enumeration;
788
+ if (propertyClass.isPrimitive()) {
789
+ if (propertyClass.isEnumeration() && propertyClass.enumeration) {
790
+ enumeration = propertyClass.schema.lookupItemSync(propertyClass.enumeration.fullName);
791
+ if (!enumeration)
792
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.ClassNotFound, `The Enumeration class '${propertyClass.enumeration.fullName}' could not be found.`);
793
+ }
794
+ const primitiveType = enumeration && enumeration.type ? enumeration.type : (propertyClass).primitiveType;
795
+ return this.readPrimitivePropertyValue(propElement, primitiveType);
796
+ }
797
+ if (propertyClass.isStruct())
798
+ return this.readStructPropertyValue(propElement, propertyClass.structClass);
799
+ return undefined;
800
+ }
801
+ readArrayPropertyValue(propElement, propertyClass) {
802
+ if (propertyClass.isPrimitive())
803
+ return this.readPrimitiveArrayValues(propElement, propertyClass.primitiveType);
804
+ if (propertyClass.isStruct())
805
+ return this.readStructArrayValues(propElement, propertyClass);
806
+ return undefined;
807
+ }
808
+ readPrimitiveArrayValues(propElement, primitiveType) {
809
+ const typeName = (0, ECObjects_1.primitiveTypeToString)(primitiveType);
810
+ const children = this.getElementChildrenByTagName(propElement, typeName);
811
+ const values = [];
812
+ for (const child of children) {
813
+ const value = this.readPrimitivePropertyValue(child, primitiveType);
814
+ values.push(value);
815
+ }
816
+ return values;
817
+ }
818
+ readStructArrayValues(propElement, propertyClass) {
819
+ const children = this.getElementChildren(propElement);
820
+ const values = [];
821
+ for (const child of children) {
822
+ const value = this.readStructPropertyValue(child, propertyClass.structClass);
823
+ values.push(value);
824
+ }
825
+ return values;
826
+ }
827
+ readStructPropertyValue(propElement, structClass) {
828
+ const structObj = {};
829
+ const children = this.getElementChildren(propElement);
830
+ for (const child of children) {
831
+ const value = this.readPropertyValue(child, structClass);
832
+ if (value !== undefined)
833
+ structObj[child.tagName] = value;
834
+ }
835
+ return structObj;
836
+ }
837
+ readPrimitivePropertyValue(propElement, primitiveType) {
838
+ if (!propElement.textContent)
839
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Primitive property '${propElement.tagName}' has an invalid property value.`);
840
+ // TODO: Mapping all primitive types to string, number and boolean
841
+ // for now. Need to review with IModelJs.
842
+ switch (primitiveType) {
843
+ case ECObjects_1.PrimitiveType.String:
844
+ case ECObjects_1.PrimitiveType.Binary: /** TODO - Currently treated as strings */
845
+ case ECObjects_1.PrimitiveType.IGeometry: /** TODO - Currently treated as strings */
846
+ return propElement.textContent;
847
+ case ECObjects_1.PrimitiveType.DateTime:
848
+ return this.getDatePropertyValue(propElement.textContent, propElement.tagName);
849
+ case ECObjects_1.PrimitiveType.Point2d:
850
+ return this.getPoint2DPropertyValue(propElement.textContent, propElement.tagName);
851
+ case ECObjects_1.PrimitiveType.Point3d:
852
+ return this.getPoint3DPropertyValue(propElement.textContent, propElement.tagName);
853
+ case ECObjects_1.PrimitiveType.Boolean:
854
+ return this.getBooleanPropertyValue(propElement.textContent, propElement.tagName);
855
+ case ECObjects_1.PrimitiveType.Integer:
856
+ case ECObjects_1.PrimitiveType.Long:
857
+ return this.getIntegerPropertyValue(propElement.textContent, propElement.tagName);
858
+ case ECObjects_1.PrimitiveType.Double:
859
+ return this.getDoublePropertyValue(propElement.textContent, propElement.tagName);
860
+ default:
861
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Primitive property '${propElement.tagName}' has an invalid primitive type.`);
862
+ }
863
+ }
864
+ getBooleanPropertyValue(propValue, propName) {
865
+ if (propValue.toLowerCase() === "true" ||
866
+ Number.parseInt(propValue, 10) > 0) {
867
+ return true;
868
+ }
869
+ else if (propValue.toLowerCase() === "false" ||
870
+ Number.parseInt(propValue, 10) === 0) {
871
+ return false;
872
+ }
873
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. An boolean value was expected.`);
874
+ }
875
+ getIntegerPropertyValue(propValue, propName) {
876
+ const result = Number.parseFloat(propValue);
877
+ if (isNaN(result) || result % 1 !== 0)
878
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. An integer value was expected.`);
879
+ return result;
880
+ }
881
+ getDatePropertyValue(propValue, propName) {
882
+ const result = Number.parseInt(propValue, 10);
883
+ if (isNaN(result))
884
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A date in milliseconds was expected.`);
885
+ return new Date(result);
886
+ }
887
+ getDoublePropertyValue(propValue, propName) {
888
+ const result = Number.parseFloat(propValue);
889
+ if (isNaN(result))
890
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A double value was expected.`);
891
+ return result;
892
+ }
893
+ getPoint2DPropertyValue(propValue, propName) {
894
+ const result = propValue.split(",");
895
+ if (result.length !== 2) {
896
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 2D value was expected.`);
897
+ }
898
+ const x = Number.parseFloat(result[0]);
899
+ const y = Number.parseFloat(result[1]);
900
+ if (isNaN(x) || isNaN(y))
901
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 2D value was expected.`);
902
+ return { x, y };
903
+ }
904
+ getPoint3DPropertyValue(propValue, propName) {
905
+ const result = propValue.split(",");
906
+ if (result.length !== 3) {
907
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 3D value was expected.`);
908
+ }
909
+ const x = Number.parseFloat(result[0]);
910
+ const y = Number.parseFloat(result[1]);
911
+ const z = Number.parseFloat(result[2]);
912
+ if (isNaN(x) || isNaN(y) || isNaN(z))
913
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `Property '${propName}' has an invalid property value. A Point 3D value was expected.`);
914
+ return { x, y, z };
915
+ }
916
+ isSchemaFullNameValidForVersion(schemaFullName, ecXmlVersion) {
917
+ const schemaNameParts = schemaFullName.split(".");
918
+ if ((ecXmlVersion.readVersion >= 3 && ecXmlVersion.writeVersion >= 2) || ecXmlVersion.readVersion > 3) {
919
+ if (schemaNameParts.length < 4)
920
+ return false;
921
+ }
922
+ else {
923
+ if (schemaNameParts.length < 3)
924
+ return false;
925
+ }
926
+ return true;
927
+ }
928
+ parseXmlNamespace(xmlNamespace) {
929
+ const regEx = new RegExp(`^${ECXML_URI}\\.([0-9]+)\\.([0-9]+)$`);
930
+ const match = xmlNamespace.match(regEx);
931
+ if (!match)
932
+ return;
933
+ const readVersion = parseInt(match[1], 10);
934
+ const writeVersion = parseInt(match[2], 10);
935
+ return { readVersion, writeVersion };
936
+ }
937
+ getQualifiedTypeName(rawTypeName) {
938
+ const nameParts = rawTypeName.split(":");
939
+ if (nameParts.length !== 2)
940
+ return `${this._schemaName}.${rawTypeName}`;
941
+ if (nameParts[0].toLowerCase() === this._schemaAlias.toLowerCase())
942
+ return `${this._schemaName}.${nameParts[1]}`;
943
+ if (this._schemaReferenceNames.has(nameParts[0].toLowerCase()))
944
+ return `${this._schemaReferenceNames.get(nameParts[0].toLowerCase())}.${nameParts[1]}`;
945
+ throw new Exception_1.ECObjectsError(Exception_1.ECObjectsStatus.InvalidSchemaXML, `No valid schema found for alias ${nameParts[0]}`);
946
+ }
947
+ /** The rest of the API uses the full name format of `{SchemaName}.{SchemaItemName}`,
948
+ * meaning all of the references in the format string need to be changed.
949
+ */
950
+ getQualifiedPresentationUnits(presentationUnits) {
951
+ const res = [];
952
+ for (const presentationUnit of presentationUnits) {
953
+ // we split the presentation unit by square parantheses [ ], f:DefaultReal(6)[u:FT|feet] will be splitted into f:DefaultReal(6) and u:FT|feet
954
+ // we format the first one and the next one will be put into [ ] again
955
+ const presentationUnitFormats = presentationUnit.split(/[\[\]]/g);
956
+ let qualifiedPresentation = "";
957
+ qualifiedPresentation = this.getQualifiedTypeName(presentationUnitFormats[0]);
958
+ if (presentationUnitFormats.length > 1) {
959
+ for (let i = 1; i < presentationUnitFormats.length; ++i) {
960
+ if (presentationUnitFormats[i].length === 0)
961
+ continue;
962
+ const verticalSlashIdx = presentationUnitFormats[i].indexOf("|");
963
+ const overrideFormat = this.getQualifiedTypeName(presentationUnitFormats[i].slice(0, verticalSlashIdx));
964
+ const formatLabel = presentationUnitFormats[i].slice(verticalSlashIdx);
965
+ qualifiedPresentation += `[${overrideFormat}${formatLabel}]`;
966
+ }
967
+ }
968
+ res.push(qualifiedPresentation);
969
+ }
970
+ return res;
971
+ }
972
+ }
973
+ exports.XmlParser = XmlParser;
974
974
  //# sourceMappingURL=XmlParser.js.map