abstract class RelationHandler { protected relations : Array; public constructor (...relations : Array ) { relations.forEach(relation => { relation.setHandler(this); }); this.relations = relations; } public addRelation (relation : Relation) { this.relations.push(relation); relation.setHandler(this); } public abstract setRelation (relation : Relation, left : any, right : any, value? : any) : boolean; } abstract class Relation { public handler : RelationHandler; public setHandler (handler : RelationHandler) { this.handler = handler; } public hasHandler () { return this.handler != undefined; } public abstract setRelation (left : any, right : any, value? : any) : void; public abstract unsetRight (right : any) : void; public abstract unsetLeft (left : any) : void; public abstract getLeft (right : any) : any; public abstract getRight (left : any) : any; public static createString (obj1 : any, obj2 : any) : string { if (obj1 instanceof Object && obj2 instanceof Object) { let id1 = Relation.getId(obj1); let id2 = Relation.getId(obj2); return id1 < id2 ? (id1 + ";" + id2) : (id2 + ";" + id1); } } private static objectCount = 0; private static objectIdField = "_RELATIONINTERNALID"; /** * if getId >= 0, then obj is NOT an Object * if getId < 0, then obj is an Object * @param obj * @returns {number} */ public static getId (obj : Object) : number { if (obj[Relation.objectIdField] == undefined) { obj[Relation.objectIdField] = Relation.objectCount++; } return obj[Relation.objectIdField]; } }