UNPKG

@itwin/ecschema-metadata

Version:

ECObjects core concepts in typescript

87 lines 3.85 kB
/** * Utility class for working with Schema graphs. * @internal */ export class SchemaGraphUtil { /** * Creates a flattened list of schemas in topological order, typically used before schema import * so that dependent schemas are processed after their references. * @param insertSchema The schema to be imported. * @param schemas The schema collection that will hold the ordered schemas. If null, the collection * will be created internally and passed along during recursive calls. */ static buildDependencyOrderedSchemaList(insertSchema, schemas) { if (!schemas) schemas = []; const lookupFn = (schema, referenceKey) => { return schema.references.find((s) => s.schemaKey.name === referenceKey.name); }; this.insertSchemaInDependencyOrderedList(schemas, insertSchema, lookupFn); for (const reference of insertSchema.references) { this.buildDependencyOrderedSchemaList(reference, schemas); } return schemas; } /** * Returns a flat list of schemas in topological order, typically used before schema import * so that dependent schemas are processed after their references. This method does not alter * the original schemaInfos array. * @param schemaInfos The schema collection that will hold the ordered schemas. * @returns A list of schemas in topological order. */ static buildDependencyOrderedSchemaInfoList(schemaInfos) { const sortedList = []; const lookupFn = (_schema, reference) => { return schemaInfos.find((s) => s.schemaKey.name === reference.name); }; for (const schemaInfo of schemaInfos) { this.insertSchemaInDependencyOrderedList(sortedList, schemaInfo, lookupFn); } return sortedList; } /** * Indicates if the given Schema references the possibleDependency Schema. * @param schema The possible dependent schema. * @param possibleDependency The possible Schema dependency. */ static dependsOn(schema, possibleDependency, lookup) { if (this.directlyReferences(schema, possibleDependency)) return true; // search for dependencies in indirect references for (const referenceInfo of schema.references) { const reference = lookup(schema, referenceInfo.schemaKey); if (reference && this.dependsOn(reference, possibleDependency, lookup)) return true; } return false; } /** * Indicates if the given Schema directly references the possiblyReferencedSchema Schema. * @param schema The possible parent schema. * @param possibleDependency The Schema that may be referenced. */ static directlyReferences(schema, possiblyReferencedSchema) { return schema.references.some((ref) => ref.schemaKey.name === possiblyReferencedSchema.schemaKey.name); } /** * Helper method that manages the insertion of a Schema into the schemas collection * based on the topological ordering algorithm. * @param schemas The ordered collection. * @param insert The instance to insert. */ static insertSchemaInDependencyOrderedList(orderedList, insert, lookup) { if (orderedList.includes(insert)) return; for (let i = orderedList.length - 1; i >= 0; --i) { const schema = orderedList[i]; if (this.dependsOn(insert, schema, lookup)) { // insert right after the referenced schema in the list const index = orderedList.indexOf(schema); orderedList.splice(index + 1, 0, insert); return; } } orderedList.splice(0, 0, insert); } } //# sourceMappingURL=SchemaGraphUtil.js.map