UNPKG

@itwin/ecschema-metadata

Version:

ECObjects core concepts in typescript

330 lines • 13.8 kB
/*--------------------------------------------------------------------------------------------- * 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 */ import { XmlSerializationUtils } from "../Deserialization/XmlSerializationUtils"; import { SchemaItemType } from "../ECObjects"; import { ECSchemaError, ECSchemaStatus } from "../Exception"; import { BaseFormat, FormatTraits, formatTraitsToArray, FormatType, ShowSignOption, } from "@itwin/core-quantity"; import { InvertedUnit } from "./InvertedUnit"; import { SchemaItem } from "./SchemaItem"; import { Unit } from "./Unit"; import { DelayedPromiseWithProps } from "../DelayedPromise"; /** * @public @preview */ export class Format extends SchemaItem { schemaItemType = Format.schemaItemType; /** @internal */ static get schemaItemType() { return SchemaItemType.Format; } _base; _units; /** @internal */ constructor(schema, name) { super(schema, name); this._base = new BaseFormat(name); } get roundFactor() { return this._base.roundFactor; } get type() { return this._base.type; } get precision() { return this._base.precision; } get minWidth() { return this._base.minWidth; } get scientificType() { return this._base.scientificType; } get showSignOption() { return this._base.showSignOption; } get decimalSeparator() { return this._base.decimalSeparator; } get thousandSeparator() { return this._base.thousandSeparator; } get uomSeparator() { return this._base.uomSeparator; } get stationSeparator() { return this._base.stationSeparator; } get stationOffsetSize() { return this._base.stationOffsetSize; } get stationBaseFactor() { return this._base.stationBaseFactor; } get formatTraits() { return this._base.formatTraits; } get spacer() { return this._base.spacer; } get includeZero() { return this._base.includeZero; } get units() { return this._units; } parseFormatTraits(formatTraitsFromJson) { return this._base.parseFormatTraits(formatTraitsFromJson); } hasFormatTrait(formatTrait) { return this._base.hasFormatTraitSet(formatTrait); } /** * Adds a Unit, or InvertedUnit, with an optional label override. * @param unit The Unit, or InvertedUnit, to add to this Format. * @param label A label that overrides the label defined within the Unit when a value is formatted. * @internal */ addUnit(unit, label) { if (undefined === this._units) this._units = []; else { // Validate that a duplicate is not added. for (const existingUnit of this._units) { if (unit.fullName.toLowerCase() === existingUnit[0].fullName.toLowerCase()) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `The Format ${this.fullName} has duplicate units, '${unit.fullName}'.`); // TODO: Validation - this should be a validation error not a hard failure. } } this._units.push([unit, label]); } /** * * @param precision * @internal */ setPrecision(precision) { this._base.precision = precision; } typecheck(formatProps) { this._base.loadFormatProperties(formatProps); if (undefined !== formatProps.composite) { // TODO: This is duplicated below when the units need to be processed... if (undefined !== formatProps.composite.includeZero) this._base.includeZero = formatProps.composite.includeZero; if (undefined !== formatProps.composite.spacer) { if (formatProps.composite.spacer.length > 1) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `The Format ${this.fullName} has a composite with an invalid 'spacer' attribute. It should be an empty or one character string.`); this._base.spacer = formatProps.composite.spacer; } // Composite requires 1-4 units if (formatProps.composite.units.length <= 0 || formatProps.composite.units.length > 4) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `The Format ${this.fullName} has an invalid 'Composite' attribute. It should have 1-4 units.`); } } fromJSONSync(formatProps) { super.fromJSONSync(formatProps); this.typecheck(formatProps); if (undefined === formatProps.composite) return; // Units are separated from the rest of the deserialization because of the need to have separate sync and async implementation for (const unit of formatProps.composite.units) { const newUnit = this.schema.lookupItemSync(unit.name); if (undefined === newUnit || (!Unit.isUnit(newUnit) && !InvertedUnit.isInvertedUnit(newUnit))) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, ``); if (Unit.isUnit(newUnit)) this.addUnit(new DelayedPromiseWithProps(newUnit.key, async () => newUnit), unit.label); else if (InvertedUnit.isInvertedUnit(newUnit)) this.addUnit(new DelayedPromiseWithProps(newUnit.key, async () => newUnit), unit.label); } } async fromJSON(formatProps) { await super.fromJSON(formatProps); this.typecheck(formatProps); if (undefined === formatProps.composite) return; // Units are separated from the rest of the deserialization because of the need to have separate sync and async implementation for (const unit of formatProps.composite.units) { const newUnit = await this.schema.lookupItem(unit.name); if (undefined === newUnit || (!Unit.isUnit(newUnit) && !InvertedUnit.isInvertedUnit(newUnit))) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, ``); if (Unit.isUnit(newUnit)) this.addUnit(new DelayedPromiseWithProps(newUnit.key, async () => newUnit), unit.label); else if (InvertedUnit.isInvertedUnit(newUnit)) this.addUnit(new DelayedPromiseWithProps(newUnit.key, async () => newUnit), unit.label); } } /** * Save this Format's properties to an object for serializing to JSON. * @param standalone Serialization includes only this object (as opposed to the full schema). * @param includeSchemaVersion Include the Schema's version information in the serialized object. */ toJSON(standalone = false, includeSchemaVersion = false) { const schemaJson = super.toJSON(standalone, includeSchemaVersion); schemaJson.type = this.type; schemaJson.precision = this.precision; // this._spacer = " "; // this._includeZero = true; // Serialize the minimal amount of information needed so anything that is the same as the default, do not serialize. if (0.0 !== this.roundFactor) schemaJson.roundFactor = this.roundFactor; if (ShowSignOption.OnlyNegative !== this.showSignOption) schemaJson.showSignOption = this.showSignOption; if (FormatTraits.Uninitialized !== this.formatTraits) schemaJson.formatTraits = formatTraitsToArray(this.formatTraits); if ("." !== this.decimalSeparator) schemaJson.decimalSeparator = this.decimalSeparator; if ("," !== this.thousandSeparator) schemaJson.thousandSeparator = this.thousandSeparator; if (" " !== this.uomSeparator) schemaJson.uomSeparator = this.uomSeparator; if (undefined !== this.minWidth) schemaJson.minWidth = this.minWidth; if (FormatType.Scientific === this.type && undefined !== this.scientificType) schemaJson.scientificType = this.scientificType; if (FormatType.Station === this.type) { if (undefined !== this.stationOffsetSize) schemaJson.stationOffsetSize = this.stationOffsetSize; if (" " !== this.stationSeparator) schemaJson.stationSeparator = this.stationSeparator; } if (undefined === this.units) return schemaJson; schemaJson.composite = {}; if (" " !== this.spacer) schemaJson.composite.spacer = this.spacer; if (true !== this.includeZero) schemaJson.composite.includeZero = this.includeZero; schemaJson.composite.units = []; for (const unit of this.units) { schemaJson.composite.units.push({ name: unit[0].fullName, label: unit[1], }); } return schemaJson; } /** @internal */ async toXml(schemaXml) { const itemElement = await super.toXml(schemaXml); itemElement.setAttribute("type", this.type.toLowerCase()); itemElement.setAttribute("precision", this.precision.toString()); itemElement.setAttribute("roundFactor", this.roundFactor.toString()); itemElement.setAttribute("showSignOption", this.showSignOption); itemElement.setAttribute("decimalSeparator", this.decimalSeparator); itemElement.setAttribute("thousandSeparator", this.thousandSeparator); itemElement.setAttribute("uomSeparator", this.uomSeparator); itemElement.setAttribute("stationSeparator", this.stationSeparator); if (undefined !== this.minWidth) itemElement.setAttribute("minWidth", this.minWidth.toString()); if (undefined !== this.scientificType) itemElement.setAttribute("scientificType", this.scientificType); if (undefined !== this.stationOffsetSize) itemElement.setAttribute("stationOffsetSize", this.stationOffsetSize.toString()); const formatTraits = formatTraitsToArray(this.formatTraits); if (formatTraits.length > 0) itemElement.setAttribute("formatTraits", formatTraits.join("|")); if (undefined !== this.units) { const compositeElement = schemaXml.createElement("Composite"); if (undefined !== this.spacer) compositeElement.setAttribute("spacer", this.spacer); if (undefined !== this.includeZero) compositeElement.setAttribute("includeZero", this.includeZero.toString()); for (const [unit, label] of this.units) { const resolvedUnit = await unit; const unitElement = schemaXml.createElement("Unit"); if (undefined !== label) unitElement.setAttribute("label", label); const unitName = XmlSerializationUtils.createXmlTypedName(this.schema, resolvedUnit.schema, resolvedUnit.name); unitElement.textContent = unitName; compositeElement.appendChild(unitElement); } ; itemElement.appendChild(compositeElement); } return itemElement; } /** * @internal */ setFormatType(formatType) { this._base.type = formatType; } /** * @internal */ setRoundFactor(roundFactor) { this._base.roundFactor = roundFactor; } /** * @internal */ setShowSignOption(signOption) { this._base.showSignOption = signOption; } /** * @internal */ setDecimalSeparator(separator) { this._base.decimalSeparator = separator; } /** * @internal */ setThousandSeparator(separator) { this._base.thousandSeparator = separator; } /** * @internal */ setUomSeparator(separator) { this._base.uomSeparator = separator; } /** * @internal */ setStationSeparator(separator) { this._base.stationSeparator = separator; } /** * @internal */ setStationOffsetSize(stationOffsetSize) { this._base.stationOffsetSize = stationOffsetSize; } /** * @internal */ setStationBaseFactor(stationBaseFactor) { this._base.stationBaseFactor = stationBaseFactor; } /** * @internal */ setScientificType(scientificType) { this._base.scientificType = scientificType; } /** * @internal */ setMinWidth(minWidth) { this._base.minWidth = minWidth; } /** * @internal */ setSpacer(spacer) { this._base.spacer = spacer; } /** * @internal */ setIncludeZero(includeZero) { this._base.includeZero = includeZero; } /** * @internal */ setFormatTraits(formatTraits) { this._base.formatTraits = formatTraits; } /** * @internal */ setUnits(units) { this._units = units; } /** Type guard to check if the SchemaItem is of type Format. * @param item The SchemaItem to check. * @returns True if the item is a Format, false otherwise. */ static isFormat(item) { if (item && item.schemaItemType === SchemaItemType.Format) return true; return false; } /** * Type assertion to check if the SchemaItem is of type Format. * @param item The SchemaItem to check. * @returns The item cast to Format if it is a Format, undefined otherwise. * @internal */ static assertIsFormat(item) { if (!this.isFormat(item)) throw new ECSchemaError(ECSchemaStatus.InvalidSchemaItemType, `Expected '${SchemaItemType.Format}' (Format)`); } } /** * @internal * An abstract class used for schema editing. */ export class MutableFormat extends Format { } //# sourceMappingURL=Format.js.map