UNPKG

@itwin/ecschema-metadata

Version:

ECObjects core concepts in typescript

189 lines • 8.56 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.SchemaFormatsProvider = void 0; const Context_1 = require("./Context"); const SchemaKey_1 = require("./SchemaKey"); const SchemaItem_1 = require("./Metadata/SchemaItem"); const Format_1 = require("./Metadata/Format"); const core_bentley_1 = require("@itwin/core-bentley"); const KindOfQuantity_1 = require("./Metadata/KindOfQuantity"); const OverrideFormat_1 = require("./Metadata/OverrideFormat"); const loggerCategory = "SchemaFormatsProvider"; /** * Provides default formats and kind of quantities from a given SchemaContext or SchemaLocater. * @beta */ class SchemaFormatsProvider { _context; _unitSystem; _formatsRetrieved = new Set(); onFormatsChanged = new core_bentley_1.BeEvent(); /** * * @param contextOrLocater The SchemaContext or a different ISchemaLocater implementation used to retrieve the schema. The SchemaContext * class implements the ISchemaLocater interface. If the provided locater is not a SchemaContext instance a new SchemaContext will be * created and the locater will be added. * @param unitSystem Used to lookup a default format through a schema specific algorithm, when the format retrieved is associated with a KindOfQuantity. */ constructor(contextOrLocater, unitSystem) { if (contextOrLocater instanceof Context_1.SchemaContext) { this._context = contextOrLocater; } else { this._context = new Context_1.SchemaContext(); this._context.addLocater(contextOrLocater); } this._unitSystem = unitSystem; } get context() { return this._context; } get unitSystem() { return this._unitSystem; } set unitSystem(unitSystem) { this._unitSystem = unitSystem; this.clear(); } clear() { const formatsChanged = Array.from(this._formatsRetrieved); this._formatsRetrieved.clear(); this.onFormatsChanged.raiseEvent({ formatsChanged }); } /** When using a presentation unit from a KindOfQuantity, the label and description should come from the KindOfQuantity */ convertToFormatDefinition(format, kindOfQuantity) { // Destructure all properties except 'rest' // eslint-disable-next-line @typescript-eslint/no-unused-vars const { name, label, description, $schema, schema, schemaVersion, schemaItemType, // eslint-disable-next-line @typescript-eslint/no-unused-vars customAttributes, originalECSpecMajorVersion, originalECSpecMinorVersion, ...rest } = format; return { ...rest, name: kindOfQuantity.fullName, label: kindOfQuantity.label ?? format.label, description: kindOfQuantity.description ?? format.description, }; } async getKindOfQuantityFormatFromSchema(itemKey) { let kindOfQuantity; try { kindOfQuantity = await this._context.getSchemaItem(itemKey, KindOfQuantity_1.KindOfQuantity); } catch { core_bentley_1.Logger.logError(loggerCategory, `Failed to find KindOfQuantity ${itemKey.fullName}`); return undefined; } if (!kindOfQuantity) { return undefined; } // Find the first presentation format that matches the provided unit system. const unitSystemMatchers = getUnitSystemGroupMatchers(this._unitSystem); const presentationFormats = kindOfQuantity.presentationFormats; for (const matcher of unitSystemMatchers) { for (const lazyFormat of presentationFormats) { const format = await lazyFormat; const unit = await (format.units && format.units[0][0]); if (!unit) { continue; } const currentUnitSystem = await unit.unitSystem; if (currentUnitSystem && matcher(currentUnitSystem)) { this._formatsRetrieved.add(itemKey.fullName); const props = (0, OverrideFormat_1.getFormatProps)(format); return this.convertToFormatDefinition(props, kindOfQuantity); } } } // If no matching presentation format was found, use persistence unit format if it matches unit system. const persistenceUnit = await kindOfQuantity.persistenceUnit; const persistenceUnitSystem = await persistenceUnit?.unitSystem; if (persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) { this._formatsRetrieved.add(itemKey.fullName); const props = getPersistenceUnitFormatProps(persistenceUnit); return this.convertToFormatDefinition(props, kindOfQuantity); } const defaultFormat = kindOfQuantity.defaultPresentationFormat; if (!defaultFormat) { return undefined; } this._formatsRetrieved.add(itemKey.fullName); const defaultProps = (0, OverrideFormat_1.getFormatProps)(await defaultFormat); return this.convertToFormatDefinition(defaultProps, kindOfQuantity); } /** * Retrieves a Format from a SchemaContext. If the format is part of a KindOfQuantity, the first presentation format in the KindOfQuantity that matches the current unit system will be retrieved. * If no presentation format matches the current unit system, the persistence unit format will be retrieved if it matches the current unit system. * Else, the default presentation format will be retrieved. * @param name The full name of the Format or KindOfQuantity. * @returns */ async getFormat(name) { const [schemaName, schemaItemName] = SchemaItem_1.SchemaItem.parseFullName(name); const schemaKey = new SchemaKey_1.SchemaKey(schemaName); let schema; try { schema = await this._context.getSchema(schemaKey); } catch { core_bentley_1.Logger.logError(loggerCategory, `Failed to find schema ${schemaName}`); return undefined; } if (!schema) { return undefined; } const itemKey = new SchemaKey_1.SchemaItemKey(schemaItemName, schema.schemaKey); if (schema.name === "Formats") { let format; try { format = await this._context.getSchemaItem(itemKey, Format_1.Format); } catch { core_bentley_1.Logger.logError(loggerCategory, `Failed to find Format ${itemKey.fullName}`); return undefined; } if (!format) { return undefined; } return format.toJSON(true); } return this.getKindOfQuantityFormatFromSchema(itemKey); } } exports.SchemaFormatsProvider = SchemaFormatsProvider; function getUnitSystemGroupMatchers(groupKey) { function createMatcher(name) { const names = Array.isArray(name) ? name : [name]; return (unitSystem) => names.some((n) => n === unitSystem.name.toUpperCase()); } switch (groupKey) { case "imperial": return ["IMPERIAL", "USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher); case "metric": return [["SI", "METRIC"], "INTERNATIONAL", "FINANCE"].map(createMatcher); case "usCustomary": return ["USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher); case "usSurvey": return ["USSURVEY", "USCUSTOM", "INTERNATIONAL", "FINANCE"].map(createMatcher); } return []; } function getPersistenceUnitFormatProps(persistenceUnit) { // Same as Format "DefaultRealU" in Formats ecschema return { formatTraits: ["keepSingleZero", "keepDecimalPoint", "showUnitLabel"], precision: 6, type: "Decimal", composite: { units: [ { name: persistenceUnit.fullName, label: persistenceUnit.label, }, ], }, }; } //# sourceMappingURL=SchemaFormatsProvider.js.map