UNPKG

@itwin/ecschema-metadata

Version:

ECObjects core concepts in typescript

174 lines 7.82 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 { DelayedPromiseWithProps } from "../DelayedPromise"; import { XmlSerializationUtils } from "../Deserialization/XmlSerializationUtils"; import { SchemaItemType } from "../ECObjects"; import { ECSchemaError, ECSchemaStatus } from "../Exception"; import { Phenomenon } from "./Phenomenon"; import { SchemaItem } from "./SchemaItem"; import { UnitSystem } from "./UnitSystem"; /** * An abstract class that adds the ability to define Units and everything that goes with them, within an ECSchema as a * first-class concept is to allow the iModel to not be dependent on any hard-coded Units * @public @preview */ export class Unit extends SchemaItem { schemaItemType = Unit.schemaItemType; /** @internal */ static get schemaItemType() { return SchemaItemType.Unit; } _phenomenon; _unitSystem; _definition; _numerator; _denominator; _offset; /** @internal */ constructor(schema, name) { super(schema, name); this._definition = ""; } get phenomenon() { return this._phenomenon; } get unitSystem() { return this._unitSystem; } get definition() { return this._definition; } get numerator() { return this._numerator ?? 1.0; } get offset() { return this._offset ?? 0.0; } get denominator() { return this._denominator ?? 1.0; } get hasNumerator() { return (this._numerator !== undefined); } get hasOffset() { return (this._offset !== undefined); } get hasDenominator() { return (this._denominator !== undefined); } /** * Returns true if a conversion can be calculated between the input units * @alpha */ static async areCompatible(unitA, unitB) { const unitAPhenomenon = await unitA.phenomenon; const unitBPhenomenon = await unitB.phenomenon; if (!unitAPhenomenon || !unitBPhenomenon || !unitAPhenomenon.key.matches(unitBPhenomenon.key)) return false; return true; } /** * Type guard to check if the SchemaItem is of type Unit. * @param item The SchemaItem to check. * @returns True if the item is a Unit, false otherwise. */ static isUnit(item) { if (item && item.schemaItemType === SchemaItemType.Unit) return true; return false; } /** * Save this Unit'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.phenomenon = this.phenomenon.fullName; schemaJson.unitSystem = this.unitSystem.fullName; schemaJson.definition = this.definition; if (this.hasNumerator) schemaJson.numerator = this.numerator; if (this.hasDenominator) schemaJson.denominator = this.denominator; if (this.hasOffset) schemaJson.offset = this.offset; return schemaJson; } /** @internal */ async toXml(schemaXml) { const itemElement = await super.toXml(schemaXml); const phenomenon = await this.phenomenon; if (undefined !== phenomenon) { const phenomenonName = XmlSerializationUtils.createXmlTypedName(this.schema, phenomenon.schema, phenomenon.name); itemElement.setAttribute("phenomenon", phenomenonName); } const unitSystem = await this.unitSystem; if (undefined !== unitSystem) { const unitSystemName = XmlSerializationUtils.createXmlTypedName(this.schema, unitSystem.schema, unitSystem.name); itemElement.setAttribute("unitSystem", unitSystemName); } itemElement.setAttribute("definition", this.definition); if (this.hasNumerator) itemElement.setAttribute("numerator", this.numerator.toString()); if (this.hasDenominator) itemElement.setAttribute("denominator", this.denominator.toString()); if (this.hasOffset) itemElement.setAttribute("offset", this.offset.toString()); return itemElement; } fromJSONSync(unitProps) { super.fromJSONSync(unitProps); const phenomenonSchemaItemKey = this.schema.getSchemaItemKey(unitProps.phenomenon); if (!phenomenonSchemaItemKey) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `Unable to locate the phenomenon ${unitProps.phenomenon}.`); this._phenomenon = new DelayedPromiseWithProps(phenomenonSchemaItemKey, async () => { const phenom = await this.schema.lookupItem(phenomenonSchemaItemKey, Phenomenon); if (undefined === phenom) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `Unable to locate the phenomenon ${unitProps.phenomenon}.`); return phenom; }); const unitSystemSchemaItemKey = this.schema.getSchemaItemKey(unitProps.unitSystem); if (!unitSystemSchemaItemKey) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `Unable to locate the unitSystem ${unitProps.unitSystem}.`); this._unitSystem = new DelayedPromiseWithProps(unitSystemSchemaItemKey, async () => { const unitSystem = await this.schema.lookupItem(unitSystemSchemaItemKey, UnitSystem); if (undefined === unitSystem) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `Unable to locate the unitSystem ${unitProps.unitSystem}.`); return unitSystem; }); if (this._definition !== "" && unitProps.definition.toLowerCase() !== this._definition.toLowerCase()) throw new ECSchemaError(ECSchemaStatus.InvalidECJson, `The Unit ${this.name} has an invalid 'definition' attribute.`); else if (this._definition === "") this._definition = unitProps.definition; if (undefined !== unitProps.numerator) { if (unitProps.numerator !== this._numerator) this._numerator = unitProps.numerator; } if (undefined !== unitProps.denominator) { if (unitProps.denominator !== this._denominator) this._denominator = unitProps.denominator; } if (undefined !== unitProps.offset) { if (unitProps.offset !== this._offset) this._offset = unitProps.offset; } } async fromJSON(unitProps) { this.fromJSONSync(unitProps); } /** @internal */ async setPhenomenon(phenomenon) { this._phenomenon = phenomenon; } /** @internal */ async setUnitSystem(unitSystem) { this._unitSystem = unitSystem; } /** @internal */ async setDefinition(definition) { this._definition = definition; } /** * Type assertion to check if the SchemaItem is of type Unit. * @param item The SchemaItem to check. * @returns The item cast to Unit if it is a Unit, undefined otherwise. * @internal */ static assertIsUnit(item) { if (!this.isUnit(item)) throw new ECSchemaError(ECSchemaStatus.InvalidSchemaItemType, `Expected '${SchemaItemType.Unit}' (Unit)`); } } /** * @internal * An abstract class used for schema editing. */ export class MutableUnit extends Unit { } //# sourceMappingURL=Unit.js.map