@itwin/ecschema-metadata
Version:
ECObjects core concepts in typescript
91 lines • 4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SchemaGraphUtil = void 0;
/**
* Utility class for working with Schema graphs.
* @internal
*/
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);
}
}
exports.SchemaGraphUtil = SchemaGraphUtil;
//# sourceMappingURL=SchemaGraphUtil.js.map