UNPKG

@itwin/ecschema-metadata

Version:

ECObjects core concepts in typescript

199 lines • 9.68 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Metadata */ Object.defineProperty(exports, "__esModule", { value: true }); exports.OverrideFormat = void 0; exports.getFormatProps = getFormatProps; const XmlSerializationUtils_1 = require("../Deserialization/XmlSerializationUtils"); const ECObjects_1 = require("../ECObjects"); const core_quantity_1 = require("@itwin/core-quantity"); const Exception_1 = require("../Exception"); /** * Overrides of a Format, from a Schema, and is SchemaItem that is used specifically on KindOfQuantity. * @public @preview */ class OverrideFormat { _precision; _units; /** The Format that this OverrideFormat is extending */ parent; /** The name of this OverrideFormat. * * This should be set to the [FormatString]($docs/bis/ec/kindofquantity/#format-string) which represents the format override. */ name; /** @internal */ constructor(parent, precision, unitAndLabels) { this.parent = parent; this.name = OverrideFormat.createOverrideFormatFullName(parent, precision, unitAndLabels); this._precision = precision; this._units = unitAndLabels; } // Properties that can be overriden get precision() { return (undefined === this._precision) ? this.parent.precision : this._precision; } get units() { return (undefined === this._units) ? this.parent.units : this._units; } // Properties that cannot be overriden get fullName() { return this.name; } get roundFactor() { return this.parent.roundFactor; } get type() { return this.parent.type; } get minWidth() { return this.parent.minWidth; } get scientificType() { return this.parent.scientificType; } get showSignOption() { return this.parent.showSignOption; } get decimalSeparator() { return this.parent.decimalSeparator; } get thousandSeparator() { return this.parent.thousandSeparator; } get uomSeparator() { return this.parent.uomSeparator; } get stationSeparator() { return this.parent.stationSeparator; } get stationOffsetSize() { return this.parent.stationOffsetSize; } get formatTraits() { return this.parent.formatTraits; } get spacer() { return this.parent.spacer; } get includeZero() { return this.parent.includeZero; } hasFormatTrait(formatTrait) { return (this.parent.formatTraits & formatTrait) === formatTrait; } /** Returns the format string of this override in the Xml full name format. * @internal */ fullNameXml(koqSchema) { let fullName = XmlSerializationUtils_1.XmlSerializationUtils.createXmlTypedName(koqSchema, this.parent.schema, this.parent.name); if (undefined !== this.precision) fullName += `(${this.precision.toString()})`; if (undefined === this._units) return fullName; for (const [unit, unitLabel] of this._units) { const unitSchema = koqSchema.context.getSchemaSync(unit.schemaKey); if (unitSchema === undefined) throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The unit schema ${unit.schemaKey} is not found in the context.`); fullName += "["; fullName += XmlSerializationUtils_1.XmlSerializationUtils.createXmlTypedName(koqSchema, unitSchema, unit.name); if (unitLabel !== undefined) fullName += `|${unitLabel}`; fullName += `]`; } return fullName; } /** * Creates a valid OverrideFormat fullName from the parent Format and overridden units. * @param parent The parent Format. * @param unitAndLabels The overridden unit and labels collection. */ static createOverrideFormatFullName(parent, precision, unitAndLabels) { let fullName = parent.fullName; if (precision) fullName += `(${precision.toString()})`; if (undefined === unitAndLabels) return fullName; for (const [unit, unitLabel] of unitAndLabels) if (undefined === unitLabel) fullName += `[${unit.fullName}]`; else fullName += `[${unit.fullName}|${unitLabel}]`; return fullName; } /** Parses the format string into the parts that make up an Override Format * @param formatString */ static parseFormatString(formatString) { const match = formatString.split(core_quantity_1.formatStringRgx); // split string based on regex groups if (undefined === match[1]) throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The format string, ${formatString}, on KindOfQuantity is missing a format.`); let precision; if (undefined !== match[2] && undefined !== match[3]) { const overrideString = match[2]; const tokens = []; let prevPos = 1; // Initial position is the character directly after the opening '(' in the override string. let currPos; // TODO need to include `,` as a valid search argument. while (-1 !== (currPos = overrideString.indexOf(")", prevPos))) { tokens.push(overrideString.substring(prevPos, currPos)); prevPos = currPos + 1; } if (overrideString.length > 0 && undefined === tokens.find((token) => { return "" !== token; // there is at least one token that is not empty. })) { throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, ``); } // The first override parameter overrides the default precision of the format const precisionIndx = 0; if (tokens.length >= precisionIndx + 1) { if (tokens[precisionIndx].length > 0) { precision = Number.parseInt(tokens[precisionIndx], 10); if (Number.isNaN(precision)) throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The format string '${formatString}' on KindOfQuantity has a precision override '${tokens[precisionIndx]}' that is not number.`); } } } let i = 4; let unitAndLabels; while (i < match.length - 1) { // The regex match ends with an empty last value, which causes problems when exactly 4 unit overrides as specified, so ignore this last empty value if (undefined === match[i]) break; // Unit override required if (undefined === match[i + 1]) throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, ``); if (undefined === unitAndLabels) unitAndLabels = []; if (undefined !== match[i + 2]) // matches '|' unitAndLabels.push([match[i + 1], match[i + 3] ?? ""]); // add unit name and label override (if '|' matches and next value is undefined, save it as an empty string) else unitAndLabels.push([match[i + 1], undefined]); // add unit name i += 4; } return { name: match[1], precision, unitAndLabels }; } /** * @internal */ static isOverrideFormat(format) { const overrideFormat = format; return overrideFormat !== undefined && overrideFormat.name !== undefined && overrideFormat.parent !== undefined && overrideFormat.parent.schemaItemType === ECObjects_1.SchemaItemType.Format; } /** * Returns a JSON object that contains the specification for the OverrideFormat where the precision and units properties have been overriden. * If the precision and/or units properties have been overriden, the returned object will contain a "name" and a "parent" property. * The "name" property identifies the OverrideFormat object itself and the "parent" property identifies the Format that has been overriden. * This method is not intended for complete serialization as it does not serialize any of the schema item properties. */ getFormatProps() { const formatJson = this.parent.toJSON(); if (this.parent.fullName !== this.fullName) { // Update name and parent properties to distinguish it from parent Format formatJson.name = this.fullName; formatJson.parent = this.parent.fullName; } // Update Precision overriden property formatJson.precision = this.precision; if (this.units !== undefined) { // Update Units overriden property const units = []; for (const unit of this.units) { units.push({ name: unit[0].fullName, label: unit[1], }); } formatJson.composite = { spacer: (this.spacer !== " ") ? this.spacer : undefined, includeZero: (this.includeZero === false) ? this.includeZero : undefined, units, }; } return formatJson; } } exports.OverrideFormat = OverrideFormat; /** * @internal */ function getFormatProps(format) { return OverrideFormat.isOverrideFormat(format) ? format.getFormatProps() : format.toJSON(); } //# sourceMappingURL=OverrideFormat.js.map