UNPKG

@itwin/core-backend

Version:
172 lines 8.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IModelElementCloneContext = void 0; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module iModels */ const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const Category_1 = require("./Category"); const NativePlatform_1 = require("./internal/NativePlatform"); const Symbols_1 = require("./internal/Symbols"); /** The context for transforming a *source* Element to a *target* Element and remapping internal identifiers to the target iModel. * @beta */ class IModelElementCloneContext { /** The source IModelDb. */ sourceDb; /** The target IModelDb. */ targetDb; /** The native import context */ _nativeContext; /** Construct a new IModelElementCloneContext. It must be initialized with `initialize`, consider using [[IModelElementCloneContext.create]] instead * @param sourceDb The source IModelDb. * @param targetDb If provided the target IModelDb. If not provided, the source and target are the same IModelDb. */ constructor(sourceDb, targetDb) { this.sourceDb = sourceDb; this.targetDb = (undefined !== targetDb) ? targetDb : sourceDb; this._nativeContext = new NativePlatform_1.IModelNative.platform.ImportContext(this.sourceDb[Symbols_1._nativeDb], this.targetDb[Symbols_1._nativeDb]); } /** perform necessary initialization to use a clone context, namely caching the reference types in the source's schemas */ async initialize() { } /** construct and initialize an IModelElementCloneContext at once, for where you construct in an async context */ static async create(...args) { const instance = new this(...args); await instance.initialize(); return instance; } /** Returns `true` if this context is for transforming between 2 iModels and `false` if it for transforming within the same iModel. */ get isBetweenIModels() { return this.sourceDb !== this.targetDb; } /** Dispose any native resources associated with this IModelElementCloneContext. */ [Symbol.dispose]() { this._nativeContext.dispose(); } /** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [Symbol.dispose] instead. */ dispose() { this[Symbol.dispose](); } /** Debugging aid that dumps the Id remapping details and other information to the specified output file. * @internal */ dump(outputFileName) { this._nativeContext.dump(outputFileName); } /** Add a rule that remaps the specified source [CodeSpec]($common) to the specified target [CodeSpec]($common). * @param sourceCodeSpecName The name of the CodeSpec from the source iModel. * @param targetCodeSpecName The name of the CodeSpec from the target iModel. * @throws [[IModelError]] if either CodeSpec could not be found. */ remapCodeSpec(sourceCodeSpecName, targetCodeSpecName) { const sourceCodeSpec = this.sourceDb.codeSpecs.getByName(sourceCodeSpecName); const targetCodeSpec = this.targetDb.codeSpecs.getByName(targetCodeSpecName); this._nativeContext.addCodeSpecId(sourceCodeSpec.id, targetCodeSpec.id); } /** Add a rule that remaps the specified source class to the specified target class. */ remapElementClass(sourceClassFullName, targetClassFullName) { this._nativeContext.addClass(sourceClassFullName, targetClassFullName); } /** Add a rule that remaps the specified source Element to the specified target Element. */ remapElement(sourceId, targetId) { this._nativeContext.addElementId(sourceId, targetId); } /** Remove a rule that remaps the specified source Element. */ removeElement(sourceId) { this._nativeContext.removeElementId(sourceId); } /** Look up a target CodeSpecId from the source CodeSpecId. * @returns the target CodeSpecId or [Id64.invalid]($bentley) if a mapping not found. */ findTargetCodeSpecId(sourceId) { if (core_bentley_1.Id64.invalid === sourceId) { return core_bentley_1.Id64.invalid; } return this._nativeContext.findCodeSpecId(sourceId); } /** Look up a target ElementId from the source ElementId. * @returns the target ElementId or [Id64.invalid]($bentley) if a mapping not found. */ findTargetElementId(sourceElementId) { if (core_bentley_1.Id64.invalid === sourceElementId) { return core_bentley_1.Id64.invalid; } return this._nativeContext.findElementId(sourceElementId); } /** Filter out geometry entries in the specified SubCategory from GeometryStreams in the target iModel. * @note It is not possible to filter out a *default* SubCategory. A request to do so will be ignored. * @see [SubCategory.isDefaultSubCategory]($backend) */ filterSubCategory(sourceSubCategoryId) { const sourceSubCategory = this.sourceDb.elements.tryGetElement(sourceSubCategoryId, Category_1.SubCategory); if (sourceSubCategory && !sourceSubCategory.isDefaultSubCategory) { this._nativeContext.filterSubCategoryId(sourceSubCategoryId); } } /** Returns `true` if there are any SubCategories being filtered. */ get hasSubCategoryFilter() { return this._nativeContext.hasSubCategoryFilter(); } /** Returns `true` if this SubCategory is being filtered. */ isSubCategoryFiltered(subCategoryId) { return this._nativeContext.isSubCategoryFiltered(subCategoryId); } /** Import the specified font from the source iModel into the target iModel. * @internal */ importFont(sourceFontNumber) { this.targetDb.clearFontMap(); // so it will be reloaded with new font info this._nativeContext.importFont(sourceFontNumber); } /** Import a single CodeSpec from the source iModel into the target iModel. * @internal */ importCodeSpec(sourceCodeSpecId) { this._nativeContext.importCodeSpec(sourceCodeSpecId); } /** Clone the specified source Element into ElementProps for the target iModel. * @internal */ cloneElement(sourceElement, cloneOptions) { const targetElementProps = this._nativeContext.cloneElement(sourceElement.id, cloneOptions); // Ensure that all NavigationProperties in targetElementProps have a defined value so "clearing" changes will be part of the JSON used for update // eslint-disable-next-line @typescript-eslint/no-deprecated sourceElement.forEachProperty((propertyName, meta) => { if ((meta.isNavigation) && (undefined === sourceElement[propertyName])) { targetElementProps[propertyName] = core_common_1.RelatedElement.none; } }, false); // exclude custom because C++ has already handled them if (this.isBetweenIModels) { // The native C++ cloneElement strips off federationGuid, want to put it back if transformation is between iModels targetElementProps.federationGuid = sourceElement.federationGuid; if (core_common_1.CodeScopeSpec.Type.Repository === this.targetDb.codeSpecs.getById(targetElementProps.code.spec).scopeType) { targetElementProps.code.scope = core_common_1.IModel.rootSubjectId; } } // unlike other references, code cannot be null. If it is null, use an empty code instead if (targetElementProps.code.scope === core_bentley_1.Id64.invalid || targetElementProps.code.spec === core_bentley_1.Id64.invalid) { targetElementProps.code = core_common_1.Code.createEmpty(); } const jsClass = this.sourceDb.getJsClass(sourceElement.classFullName); // eslint-disable-next-line @typescript-eslint/dot-notation jsClass["onCloned"](this, sourceElement.toJSON(), targetElementProps); return targetElementProps; } /** * serialize state to a sqlite database at a given path * assumes the database has not already had any context state serialized to it * @internal */ saveStateToDb(db) { this._nativeContext.saveStateToDb(db[Symbols_1._nativeDb]); } /** * load state from a sqlite database at a given path * @internal */ loadStateFromDb(db) { this._nativeContext.loadStateFromDb(db[Symbols_1._nativeDb]); } } exports.IModelElementCloneContext = IModelElementCloneContext; //# sourceMappingURL=IModelElementCloneContext.js.map