@itwin/ecschema-metadata
Version:
ECObjects core concepts in typescript
163 lines • 9.09 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { PrimitiveType, primitiveTypeToString } from "../ECObjects";
import { ECSchemaError, ECSchemaStatus } from "../Exception";
/**
* Namespace holding utility functions for serializing EC types to the EC XML format.
* @internal
*/
export var XmlSerializationUtils;
(function (XmlSerializationUtils) {
/**
* Serializes a CustomAttribute instance to the EC XML format.
* @param fullName The full name of the CustomAttribute (qualified by schema name).
* @param customAttribute The CustomAttribute instance to serialize.
* @param schemaDoc The Xml Document object holding the serialized EC Schema.
* @param schema The Schema object being serialized.
*/
async function writeCustomAttribute(fullName, customAttribute, schemaDoc, schema) {
const caClass = await schema.lookupItem(fullName);
if (!caClass)
throw new ECSchemaError(ECSchemaStatus.ClassNotFound, `The class '${fullName}' could not be found in the current schema context.`);
const nameAndNamespace = await resolveCustomAttributeNamespace(fullName, schema);
const caElement = schemaDoc.createElement(nameAndNamespace[0]);
if (nameAndNamespace[1])
caElement.setAttribute("xmlns", nameAndNamespace[1]);
for (const property of await caClass.getProperties())
await writeInstanceProperty(property, customAttribute, caElement, schemaDoc);
return caElement;
}
XmlSerializationUtils.writeCustomAttribute = writeCustomAttribute;
/**
* Serializes an EC Property instance to the EC XML format.
* @param propertyClass The Property metadata object.
* @param instance The Property instance.
* @param instanceElement The XML Element that will contain the serialized property instance.
* @param schemaDoc The Xml Document object holding the serialized EC Schema.
*/
async function writeInstanceProperty(propertyClass, instance, instanceElement, schemaDoc) {
const propertyValue = instance[propertyClass.name];
if (propertyValue === undefined)
return;
const propertyElement = schemaDoc.createElement(propertyClass.name);
instanceElement.appendChild(propertyElement);
if (propertyClass.isArray()) {
await writeArrayProperty(propertyClass, propertyValue, propertyElement, schemaDoc);
}
else if (propertyClass.isPrimitive()) {
await writePrimitiveProperty(propertyClass, propertyValue, propertyElement);
}
else if (propertyClass.isStruct()) {
await writeStructProperty(propertyClass, propertyValue, propertyElement, schemaDoc);
}
}
XmlSerializationUtils.writeInstanceProperty = writeInstanceProperty;
/**
* Serializes an EC ArrayProperty instance to the EC XML format.
* @param propertyClass The Property metadata object.
* @param propertyValue An array holding the property values.
* @param arrayElement The XML Element that will contain the serialized property instance.
* @param schemaDoc The Xml Document object holding the serialized EC Schema.
*/
async function writeArrayProperty(propertyClass, propertyValue, arrayElement, schemaDoc) {
if (propertyClass.isPrimitive()) {
const typeString = primitiveTypeToString(propertyClass.primitiveType);
for (const value of propertyValue) {
const entryElement = schemaDoc.createElement(typeString);
await writePrimitiveProperty(propertyClass, value, entryElement);
arrayElement.appendChild(entryElement);
}
}
if (propertyClass.isStruct()) {
for (const value of propertyValue) {
const structElement = schemaDoc.createElement(propertyClass.structClass.name);
arrayElement.appendChild(structElement);
await writeStructProperty(propertyClass, value, structElement, schemaDoc);
}
}
}
XmlSerializationUtils.writeArrayProperty = writeArrayProperty;
/**
* Serializes an EC StructProperty instance to the EC XML format.
* @param propertyClass The Property metadata object.
* @param propertyValue The struct object holding the property values.
* @param structElement The XML Element that will contain the serialized property instance.
* @param schemaDoc The Xml Document object holding the serialized EC Schema.
*/
async function writeStructProperty(propertyClass, propertyValue, structElement, schemaDoc) {
const structClass = propertyClass.structClass;
for (const propertyMetadata of structClass.getPropertiesSync())
await writeInstanceProperty(propertyMetadata, propertyValue, structElement, schemaDoc);
}
XmlSerializationUtils.writeStructProperty = writeStructProperty;
/**
* Serializes an EC PrimitiveProperty instance to the EC XML format.
* @param propertyClass The Property metadata object.
* @param propertyValue The struct object holding the property values.
* @param propertyElement The XML Element that will contain the serialized property instance.
*/
async function writePrimitiveProperty(propertyClass, propertyValue, propertyElement) {
let primitiveType;
if (propertyClass.isEnumeration()) {
const enumeration = await propertyClass.enumeration;
if (!enumeration)
throw new ECSchemaError(ECSchemaStatus.ClassNotFound, `The enumeration on property class '${propertyClass.fullName}' could not be found in the current schema context.`);
if (enumeration.type === undefined)
throw new ECSchemaError(ECSchemaStatus.InvalidType, `The enumeration on property class '${propertyClass.fullName}' has an invalid primitive type.`);
primitiveType = enumeration.type;
}
else
primitiveType = propertyClass.primitiveType;
switch (primitiveType) {
case PrimitiveType.String:
propertyElement.textContent = propertyValue;
return;
case PrimitiveType.Boolean:
propertyElement.textContent = propertyValue ? "True" : "False";
return;
case PrimitiveType.Integer:
case PrimitiveType.Double:
case PrimitiveType.Long:
propertyElement.textContent = propertyValue.toString();
return;
case PrimitiveType.DateTime:
propertyElement.textContent = new Date(propertyValue).getTime().toString();
return;
case PrimitiveType.Point2d:
propertyElement.textContent = `${propertyValue.x},${propertyValue.y}`;
return;
case PrimitiveType.Point3d:
propertyElement.textContent = `${propertyValue.x},${propertyValue.y},${propertyValue.z}`;
return;
case PrimitiveType.IGeometry:
case PrimitiveType.Binary:
propertyElement.textContent = propertyValue;
return;
default:
throw new ECSchemaError(ECSchemaStatus.InvalidPrimitiveType, `The property '${propertyClass.fullName}' has an invalid primitive type.`);
}
}
XmlSerializationUtils.writePrimitiveProperty = writePrimitiveProperty;
function createXmlTypedName(currentSchema, typeSchema, typeName) {
if (currentSchema.schemaKey.matches(typeSchema.schemaKey))
return typeName;
// Alias is required in Spec. It could be undefined (technically), so
// throw until fixed.
if (typeSchema.alias === undefined)
throw new ECSchemaError(ECSchemaStatus.InvalidSchemaAlias, `The schema '${typeSchema.name}' has an invalid alias.`);
return `${typeSchema.alias}:${typeName}`;
}
XmlSerializationUtils.createXmlTypedName = createXmlTypedName;
async function resolveCustomAttributeNamespace(caName, schema) {
const nameParts = caName.split(".");
if (nameParts.length === 1)
return [caName, undefined];
const attributeSchema = nameParts[0].toUpperCase() === schema.name.toUpperCase() ? schema : await schema.getReference(nameParts[0]);
if (!attributeSchema)
throw new ECSchemaError(ECSchemaStatus.UnableToLocateSchema, `Unable to resolve the namespace for CustomAttribute '${caName}' because the referenced schema '${nameParts[0]}' could not be located.`);
return [nameParts[1], `${nameParts[0]}.${attributeSchema.schemaKey.version.toString()}`];
}
})(XmlSerializationUtils || (XmlSerializationUtils = {}));
//# sourceMappingURL=XmlSerializationUtils.js.map