141 lines
4.6 KiB
TypeScript
141 lines
4.6 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
|
|
import { BaseRepository } from 'app/core/repositories/base-repository';
|
|
import { BaseViewModel, TitleInformation, ViewModelConstructor } from 'app/site/base/base-view-model';
|
|
import { BaseModel, ModelConstructor } from '../../shared/models/base/base-model';
|
|
|
|
/**
|
|
* Unifies the ModelConstructor and ViewModelConstructor.
|
|
*/
|
|
interface UnifiedConstructors {
|
|
COLLECTIONSTRING: string;
|
|
new (...args: any[]): any;
|
|
}
|
|
|
|
/**
|
|
* Every types supported: (View)ModelConstructors, repos and collectionstrings.
|
|
*/
|
|
type TypeIdentifier = UnifiedConstructors | BaseRepository<any, any, any> | string;
|
|
|
|
type CollectionStringMappedTypes = [
|
|
ModelConstructor<BaseModel>,
|
|
ViewModelConstructor<BaseViewModel>,
|
|
BaseRepository<BaseViewModel<any>, BaseModel<any>, TitleInformation>
|
|
];
|
|
|
|
/**
|
|
* Registeres the mapping between collection strings, models constructors, view
|
|
* model constructors and repositories.
|
|
* All models need to be registered!
|
|
*/
|
|
@Injectable({
|
|
providedIn: 'root'
|
|
})
|
|
export class CollectionStringMapperService {
|
|
/**
|
|
* Maps collection strings to mapping entries
|
|
*/
|
|
private collectionStringMapping: {
|
|
[collectionString: string]: CollectionStringMappedTypes;
|
|
} = {};
|
|
|
|
public constructor() {}
|
|
|
|
/**
|
|
* Registers the combination of a collection string, model, view model and repository
|
|
* @param collectionString
|
|
* @param model
|
|
*/
|
|
public registerCollectionElement<V extends BaseViewModel<M>, M extends BaseModel>(
|
|
collectionString: string,
|
|
model: ModelConstructor<M>,
|
|
viewModel: ViewModelConstructor<V>,
|
|
repository: BaseRepository<V, M, TitleInformation>
|
|
): void {
|
|
this.collectionStringMapping[collectionString] = [model, viewModel, repository];
|
|
}
|
|
|
|
/**
|
|
* @param obj The object to get the collection string from.
|
|
* @returns the collectionstring
|
|
*/
|
|
public getCollectionString(obj: TypeIdentifier): string {
|
|
if (typeof obj === 'string') {
|
|
return obj;
|
|
} else {
|
|
return obj.COLLECTIONSTRING;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @returns true, if the given collection is known by this service.
|
|
*/
|
|
public isCollectionRegistered(collectionString: string): boolean {
|
|
return !!this.collectionStringMapping[collectionString];
|
|
}
|
|
|
|
/**
|
|
* @param obj The object to get the model constructor from.
|
|
* @returns the model constructor
|
|
*/
|
|
public getModelConstructor<M extends BaseModel>(obj: TypeIdentifier): ModelConstructor<M> | null {
|
|
if (this.isCollectionRegistered(this.getCollectionString(obj))) {
|
|
return this.collectionStringMapping[this.getCollectionString(obj)][0] as ModelConstructor<M>;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param obj The object to get the view model constructor from.
|
|
* @returns the view model constructor
|
|
*/
|
|
public getViewModelConstructor<M extends BaseViewModel>(obj: TypeIdentifier): ViewModelConstructor<M> | null {
|
|
if (this.isCollectionRegistered(this.getCollectionString(obj))) {
|
|
return this.collectionStringMapping[this.getCollectionString(obj)][1] as ViewModelConstructor<M>;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param obj The object to get the repository from.
|
|
* @returns the repository
|
|
*/
|
|
public getRepository<V extends BaseViewModel, M extends BaseModel, T extends TitleInformation>(
|
|
obj: TypeIdentifier
|
|
): BaseRepository<V & T, M, T> | null {
|
|
if (this.isCollectionRegistered(this.getCollectionString(obj))) {
|
|
return this.collectionStringMapping[this.getCollectionString(obj)][2] as BaseRepository<V & T, M, T>;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @returns all registered repositories.
|
|
*/
|
|
public getAllRepositories(): BaseRepository<any, any, any>[] {
|
|
return Object.values(this.collectionStringMapping).map((types: CollectionStringMappedTypes) => types[2]);
|
|
}
|
|
|
|
/**
|
|
* Validates the given element id. It must have the form `<collection>:<id>`, with
|
|
* <collection> being a registered collection and the id a valid integer greater then 0.
|
|
*
|
|
* @param elementId The element id.
|
|
* @returns true, if the element id is valid.
|
|
*/
|
|
public isElementIdValid(elementId: any): boolean {
|
|
if (!elementId || typeof elementId !== 'string') {
|
|
return false;
|
|
}
|
|
|
|
const splitted = elementId.split(':');
|
|
if (splitted.length !== 2) {
|
|
return false;
|
|
}
|
|
|
|
const id = parseInt(splitted[1], 10);
|
|
if (isNaN(id) || id <= 0) {
|
|
return false;
|
|
}
|
|
|
|
return Object.keys(this.collectionStringMapping).some(collection => collection === splitted[0]);
|
|
}
|
|
}
|