@kephas/core
Version:
Provides a common infrastructure for all the other Kephas Framework components: ambient services, dynamic reflection, composition, application management, and others.
173 lines • 23.3 kB
JavaScript
import 'reflect-metadata';
import { Requires } from '../diagnostics/contracts/requires';
import { AppServiceInfo, AppServiceLifetime } from './appServiceInfo';
import { AppServiceMetadata, Priority } from './appServiceMetadata';
import { ServiceError } from './serviceError';
/**
* Registry for the application service information.
*
* @export
* @class AppServiceInfoRegistry
*/
export class AppServiceInfoRegistry {
/**
* Creates an instance of AppServiceInfoRegistry.
* @memberof AppServiceInfoRegistry
*/
constructor() {
this._serviceContracts = [];
this._services = [];
this.registerServiceContract(AppServiceInfoRegistry, new AppServiceInfo({
contractType: AppServiceInfoRegistry,
lifetime: AppServiceLifetime.Singleton
}));
this.registerService(AppServiceInfoRegistry, new AppServiceMetadata({
overridePriority: Priority.Low,
serviceType: AppServiceInfoRegistry,
serviceInstance: this,
}));
}
/**
* Gets the static instance of the registry.
*
* @static
* @memberof AppServiceInfoRegistry
*/
static get Instance() {
return AppServiceInfoRegistry._instance
? AppServiceInfoRegistry._instance
: (AppServiceInfoRegistry._instance = new AppServiceInfoRegistry());
}
;
/**
* Gets an iterator over service contracts.
*
* @returns {IterableIterator<AppServiceInfo>} The iterator over service contracts.
* @memberof AppServiceInfoRegistry
*/
get serviceContracts() {
return this._serviceContracts.values();
}
/**
* Gets an iterator of services.
*
* @readonly
* @type {IterableIterator<AppServiceMetadata>} The iterator over services.
* @memberof AppServiceInfoRegistry
*/
get services() {
return this._services.values();
}
/**
* Registers the provided type as a service contract.
*
* @static
* @param {AbstractType} type The type to be registered.
* @param {AppServiceInfo} appServiceInfo The service information.
* @memberof AppServiceInfoRegistry
*/
registerServiceContract(type, appServiceInfo) {
Requires.HasValue(type, 'type');
Reflect.defineMetadata(AppServiceInfoRegistry._serviceContractKey, appServiceInfo, type);
this._serviceContracts.push(appServiceInfo);
return this;
}
/**
* Registers the provided type as a service type.
*
* @static
* @param {Type<T>} type The type to be registered.
* @param {AppServiceMetadata} [metadata] Optional. The service metadata.
* @memberof AppServiceInfoRegistry
*/
registerService(type, metadata) {
Requires.HasValue(type, 'type');
const appServiceInfo = (metadata && metadata.serviceContract) || this._getContractOfService(type);
if (!appServiceInfo) {
throw new ServiceError(`The service contract for '${type.name}' could not be identified. Check that the service or one of its bases is decorated as AppServiceContract or SingletonAppServiceContract.`);
}
metadata = metadata || new AppServiceMetadata();
metadata['_serviceType'] = type;
metadata['_serviceContract'] = appServiceInfo;
let result = appServiceInfo.registerService(metadata);
if (result instanceof ServiceError) {
throw result;
}
if (result instanceof AppServiceMetadata) {
const overriddenServiceType = result.serviceType;
const overriddenIndex = this._services.findIndex(m => m.serviceType === overriddenServiceType);
if (overriddenIndex >= 0) {
this._services[overriddenIndex] = metadata;
}
result = true;
}
else if (result) {
this._services.push(metadata);
}
if (result) {
Reflect.defineMetadata(AppServiceInfoRegistry._serviceContractKey, appServiceInfo, type);
Reflect.defineMetadata(AppServiceInfoRegistry._serviceMetadataKey, metadata, type);
}
return this;
}
/**
* Gets the service contract from the provided type, if possible.
*
* @param {AbstractType} type The type assumed to be a service contract or a service type.
* @returns {(AppServiceInfo | null)} The AppServiceInfo instance or null, if the type is not a service contract.
* @memberof AppServiceInfoRegistry
*/
getServiceContract(type) {
Requires.HasValue(type, 'type');
return Reflect.getOwnMetadata(AppServiceInfoRegistry._serviceContractKey, type) || null;
}
/**
* Gets a value indicating whether a type is a service contract.
*
* @param {AbstractType} type The type assumed to be a service contract.
* @returns {boolean}
* @memberof AppServiceInfoRegistry
*/
isServiceContract(type) {
Requires.HasValue(type, 'type');
return Reflect.hasOwnMetadata(AppServiceInfoRegistry._serviceContractKey, type);
}
/**
* Gets the service metadata from the provided type, if possible.
*
* @param {AbstractType} type The type assumed to be a service type.
* @returns {(AppServiceMetadata | null)}
* @memberof AppServiceInfoRegistry
*/
getServiceMetadata(type) {
Requires.HasValue(type, 'type');
return Reflect.getOwnMetadata(AppServiceInfoRegistry._serviceMetadataKey, type) || null;
}
/**
* Gets a value indicating whether a type is a service.
*
* @param {AbstractType} type
* @returns {boolean}
* @memberof AppServiceInfoRegistry
*/
isService(type) {
Requires.HasValue(type, 'type');
return Reflect.hasOwnMetadata(AppServiceInfoRegistry._serviceMetadataKey, type);
}
_getContractOfService(type) {
while (type) {
const contract = this.getServiceContract(type);
if (contract) {
return contract;
}
const typePrototype = Object.getPrototypeOf(type.prototype);
type = typePrototype && typePrototype.constructor;
}
return null;
}
}
// metadata keys should be defined before the instance is created,
// otherwise they will be null when registering the contracts.
AppServiceInfoRegistry._serviceContractKey = 'kephas:serviceContract';
AppServiceInfoRegistry._serviceMetadataKey = 'kephas:serviceMetadata';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwU2VydmljZUluZm9SZWdpc3RyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tlcGhhcy9jb3JlL3NyYy9saWIvc2VydmljZXMvYXBwU2VydmljZUluZm9SZWdpc3RyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUU3RCxPQUFPLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQWtCOUM7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sc0JBQXNCO0lBdUIvQjs7O09BR0c7SUFDSDtRQUNJLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFFcEIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLHNCQUFzQixFQUFFLElBQUksY0FBYyxDQUNuRTtZQUNJLFlBQVksRUFBRSxzQkFBc0I7WUFDcEMsUUFBUSxFQUFFLGtCQUFrQixDQUFDLFNBQVM7U0FDekMsQ0FBQyxDQUFDLENBQUM7UUFDUixJQUFJLENBQUMsZUFBZSxDQUFDLHNCQUFzQixFQUFFLElBQUksa0JBQWtCLENBQy9EO1lBQ0ksZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLEdBQUc7WUFDOUIsV0FBVyxFQUFFLHNCQUFzQjtZQUNuQyxlQUFlLEVBQUUsSUFBSTtTQUN4QixDQUFDLENBQUMsQ0FBQztJQUNaLENBQUM7SUFsQ0Q7Ozs7O09BS0c7SUFDSSxNQUFNLEtBQUssUUFBUTtRQUN0QixPQUFPLHNCQUFzQixDQUFDLFNBQVM7WUFDbkMsQ0FBQyxD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Q3RDLDBDQUFtQixHQUFHLHdCQUF3QixDQUFDO0FBQy9DLDBDQUFtQixHQUFHLHdCQUF3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdyZWZsZWN0LW1ldGFkYXRhJztcclxuaW1wb3J0IHsgUmVxdWlyZXMgfSBmcm9tICcuLi9kaWFnbm9zdGljcy9jb250cmFjdHMvcmVxdWlyZXMnO1xyXG5pbXBvcnQgeyBBYnN0cmFjdFR5cGUsIFR5cGUgfSBmcm9tICcuLi90eXBlJztcclxuaW1wb3J0IHsgQXBwU2VydmljZUluZm8sIEFwcFNlcnZpY2VMaWZldGltZSB9IGZyb20gJy4vYXBwU2VydmljZUluZm8nO1xyXG5pbXBvcnQgeyBBcHBTZXJ2aWNlTWV0YWRhdGEsIFByaW9yaXR5IH0gZnJvbSAnLi9hcHBTZXJ2aWNlTWV0YWRhdGEnO1xyXG5pbXBvcnQgeyBTZXJ2aWNlRXJyb3IgfSBmcm9tICcuL3NlcnZpY2VFcnJvcic7XHJcblxyXG5pbnRlcmZhY2UgSUFwcFNlcnZpY2VJbmZvIHtcclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0ZXJzIGEgc2VydmljZSBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBjb250cmFjdC5cclxuICAgICAqXHJcbiAgICAgKiBAdGVtcGxhdGUgVCBUaGUgc2VydmljZSBpbXBsZW1lbnRhdGlvbiB0eXBlLlxyXG4gICAgICogQHBhcmFtIHtBcHBTZXJ2aWNlTWV0YWRhdGE8VD59IHNlcnZpY2VcclxuICAgICAqIEByZXR1cm5zIHsoYm9vbGVhbiB8IFNlcnZpY2VFcnJvciB8IEFwcFNlcnZpY2VNZXRhZGF0YTxhbnk+KX1cclxuICAgICAqIFRydWUsIGlmIHRoZSBzZXJ2aWNlIHdhcyByZWdpc3RlcmVkIHN1Y2Nlc3NmdWxseS5cclxuICAgICAqIEZhbHNlLCBpZiB0aGUgc2VydmljZSB3YXMgbm90IHJlZ2lzdGVyZWQgZHVlIHRvIGEgaGlnaGVyIG92ZXJyaWRlIHByaW9yaXR5IHNlcnZpY2UgYWxyZWFkeSByZWdpc3RlcmVkLlxyXG4gICAgICogU2VydmljZUVycm9yLCBpZiBhIHNlcnZpY2UgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHdpdGggdGhlIHNhbWUgb3ZlcnJpZGUgcHJpb3JpdHkuXHJcbiAgICAgKiBBcHBTZXJ2aWNlTWV0YWRhdGE8YW55PiwgaWYgdGhlIHNlcnZpY2UgdG8gcmVnaXN0ZXIgb3ZlcnJpZCBhbiBleGlzdGluZyBvbmUuIFRoZSBvdmVycmlkZGVuIHNlcnZpY2UgaXMgcmV0dXJuZWQuXHJcbiAgICAgKiBAbWVtYmVyb2YgQXBwU2VydmljZUluZm9cclxuICAgICAqL1xyXG4gICAgcmVnaXN0ZXJTZXJ2aWNlPFQ+KHNlcnZpY2U6IEFwcFNlcnZpY2VNZXRhZGF0YTxUPik6IGJvb2xlYW4gfCBTZXJ2aWNlRXJyb3IgfCBBcHBTZXJ2aWNlTWV0YWRhdGE8YW55PjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdHJ5IGZvciB0aGUgYXBwbGljYXRpb24gc2VydmljZSBpbmZvcm1hdGlvbi5cclxuICpcclxuICogQGV4cG9ydFxyXG4gKiBAY2xhc3MgQXBwU2VydmljZUluZm9SZWdpc3RyeVxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEFwcFNlcnZpY2VJbmZvUmVnaXN0cnkge1xyXG4gICAgLy8gbWV0YWRhdGEga2V5cyBzaG91bGQgYmUgZGVmaW5lZCBiZWZvcmUgdGhlIGluc3RhbmNlIGlzIGNyZWF0ZWQsXHJcbiAgICAvLyBvdGhlcndpc2UgdGhleSB3aWxsIGJlIG51bGwgd2hlbiByZWdpc3RlcmluZyB0aGUgY29udHJhY3RzLlxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgX3NlcnZpY2VDb250cmFjdEtleSA9ICdrZXBoYXM6c2VydmljZUNvbnRyYWN0JztcclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IF9zZXJ2aWNlTWV0YWRhdGFLZXkgPSAna2VwaGFzOnNlcnZpY2VNZXRhZGF0YSc7XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlOiBBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgc3RhdGljIGluc3RhbmNlIG9mIHRoZSByZWdpc3RyeS5cclxuICAgICAqXHJcbiAgICAgKiBAc3RhdGljXHJcbiAgICAgKiBAbWVtYmVyb2YgQXBwU2VydmljZUluZm9SZWdpc3RyeVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc3RhdGljIGdldCBJbnN0YW5jZSgpIHtcclxuICAgICAgICByZXR1cm4gQXBwU2VydmljZUluZm9SZWdpc3RyeS5faW5zdGFuY2VcclxuICAgICAgICAgICAgPyBBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5Ll9pbnN0YW5jZVxyXG4gICAgICAgICAgICA6IChBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5Ll9pbnN0YW5jZSA9IG5ldyBBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5KCkpO1xyXG4gICAgfTtcclxuXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9zZXJ2aWNlQ29udHJhY3RzOiBBcHBTZXJ2aWNlSW5mb1tdO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfc2VydmljZXM6IEFwcFNlcnZpY2VNZXRhZGF0YTxhbnk+W107XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIEFwcFNlcnZpY2VJbmZvUmVnaXN0cnkuXHJcbiAgICAgKiBAbWVtYmVyb2YgQXBwU2VydmljZUluZm9SZWdpc3RyeVxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcigpIHtcclxuICAgICAgICB0aGlzLl9zZXJ2aWNlQ29udHJhY3RzID0gW107XHJcbiAgICAgICAgdGhpcy5fc2VydmljZXMgPSBbXTtcclxuXHJcbiAgICAgICAgdGhpcy5yZWdpc3RlclNlcnZpY2VDb250cmFjdChBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5LCBuZXcgQXBwU2VydmljZUluZm8oXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGNvbnRyYWN0VHlwZTogQXBwU2VydmljZUluZm9SZWdpc3RyeSxcclxuICAgICAgICAgICAgICAgIGxpZmV0aW1lOiBBcHBTZXJ2aWNlTGlmZXRpbWUuU2luZ2xldG9uXHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICB0aGlzLnJlZ2lzdGVyU2VydmljZShBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5LCBuZXcgQXBwU2VydmljZU1ldGFkYXRhKFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBvdmVycmlkZVByaW9yaXR5OiBQcmlvcml0eS5Mb3csXHJcbiAgICAgICAgICAgICAgICBzZXJ2aWNlVHlwZTogQXBwU2VydmljZUluZm9SZWdpc3RyeSxcclxuICAgICAgICAgICAgICAgIHNlcnZpY2VJbnN0YW5jZTogdGhpcyxcclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhbiBpdGVyYXRvciBvdmVyIHNlcnZpY2UgY29udHJhY3RzLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtJdGVyYWJsZUl0ZXJhdG9yPEFwcFNlcnZpY2VJbmZvPn0gVGhlIGl0ZXJhdG9yIG92ZXIgc2VydmljZSBjb250cmFjdHMuXHJcbiAgICAgKiBAbWVtYmVyb2YgQXBwU2VydmljZUluZm9SZWdpc3RyeVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IHNlcnZpY2VDb250cmFjdHMoKTogSXRlcmFibGVJdGVyYXRvcjxBcHBTZXJ2aWNlSW5mbz4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zZXJ2aWNlQ29udHJhY3RzLnZhbHVlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhbiBpdGVyYXRvciBvZiBzZXJ2aWNlcy5cclxuICAgICAqXHJcbiAgICAgKiBAcmVhZG9ubHlcclxuICAgICAqIEB0eXBlIHtJdGVyYWJsZUl0ZXJhdG9yPEFwcFNlcnZpY2VNZXRhZGF0YT59IFRoZSBpdGVyYXRvciBvdmVyIHNlcnZpY2VzLlxyXG4gICAgICogQG1lbWJlcm9mIEFwcFNlcnZpY2VJbmZvUmVnaXN0cnlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBzZXJ2aWNlcygpOiBJdGVyYWJsZUl0ZXJhdG9yPEFwcFNlcnZpY2VNZXRhZGF0YTxhbnk+PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlcnZpY2VzLnZhbHVlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVnaXN0ZXJzIHRoZSBwcm92aWRlZCB0eXBlIGFzIGEgc2VydmljZSBjb250cmFjdC5cclxuICAgICAqXHJcbiAgICAgKiBAc3RhdGljXHJcbiAgICAgKiBAcGFyYW0ge0Fic3RyYWN0VHlwZX0gdHlwZSBUaGUgdHlwZSB0byBiZSByZWdpc3RlcmVkLlxyXG4gICAgICogQHBhcmFtIHtBcHBTZXJ2aWNlSW5mb30gYXBwU2VydmljZUluZm8gVGhlIHNlcnZpY2UgaW5mb3JtYXRpb24uXHJcbiAgICAgKiBAbWVtYmVyb2YgQXBwU2VydmljZUluZm9SZWdpc3RyeVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVnaXN0ZXJTZXJ2aWNlQ29udHJhY3QodHlwZTogQWJzdHJhY3RUeXBlLCBhcHBTZXJ2aWNlSW5mbzogQXBwU2VydmljZUluZm8pOiB0aGlzIHtcclxuICAgICAgICBSZXF1aXJlcy5IYXNWYWx1ZSh0eXBlLCAndHlwZScpO1xyXG4gICAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoQXBwU2VydmljZUluZm9SZWdpc3RyeS5fc2VydmljZUNvbnRyYWN0S2V5LCBhcHBTZXJ2aWNlSW5mbywgdHlwZSk7XHJcbiAgICAgICAgdGhpcy5fc2VydmljZUNvbnRyYWN0cy5wdXNoKGFwcFNlcnZpY2VJbmZvKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlZ2lzdGVycyB0aGUgcHJvdmlkZWQgdHlwZSBhcyBhIHNlcnZpY2UgdHlwZS5cclxuICAgICAqXHJcbiAgICAgKiBAc3RhdGljXHJcbiAgICAgKiBAcGFyYW0ge1R5cGU8VD59IHR5cGUgVGhlIHR5cGUgdG8gYmUgcmVnaXN0ZXJlZC5cclxuICAgICAqIEBwYXJhbSB7QXBwU2VydmljZU1ldGFkYXRhfSBbbWV0YWRhdGFdIE9wdGlvbmFsLiBUaGUgc2VydmljZSBtZXRhZGF0YS5cclxuICAgICAqIEBtZW1iZXJvZiBBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyByZWdpc3RlclNlcnZpY2U8VD4odHlwZTogVHlwZTxUPiwgbWV0YWRhdGE/OiBBcHBTZXJ2aWNlTWV0YWRhdGE8VD4pOiB0aGlzIHtcclxuICAgICAgICBSZXF1aXJlcy5IYXNWYWx1ZSh0eXBlLCAndHlwZScpO1xyXG4gICAgICAgIGNvbnN0IGFwcFNlcnZpY2VJbmZvID0gKG1ldGFkYXRhICYmIG1ldGFkYXRhLnNlcnZpY2VDb250cmFjdCkgfHwgdGhpcy5fZ2V0Q29udHJhY3RPZlNlcnZpY2UodHlwZSk7XHJcbiAgICAgICAgaWYgKCFhcHBTZXJ2aWNlSW5mbykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgU2VydmljZUVycm9yKGBUaGUgc2VydmljZSBjb250cmFjdCBmb3IgJyR7dHlwZS5uYW1lfScgY291bGQgbm90IGJlIGlkZW50aWZpZWQuIENoZWNrIHRoYXQgdGhlIHNlcnZpY2Ugb3Igb25lIG9mIGl0cyBiYXNlcyBpcyBkZWNvcmF0ZWQgYXMgQXBwU2VydmljZUNvbnRyYWN0IG9yIFNpbmdsZXRvbkFwcFNlcnZpY2VDb250cmFjdC5gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1ldGFkYXRhID0gbWV0YWRhdGEgfHwgbmV3IEFwcFNlcnZpY2VNZXRhZGF0YSgpO1xyXG4gICAgICAgIG1ldGFkYXRhWydfc2VydmljZVR5cGUnXSA9IHR5cGU7XHJcbiAgICAgICAgbWV0YWRhdGFbJ19zZXJ2aWNlQ29udHJhY3QnXSA9IGFwcFNlcnZpY2VJbmZvO1xyXG5cclxuICAgICAgICBsZXQgcmVzdWx0ID0gKGFwcFNlcnZpY2VJbmZvIGFzIHVua25vd24gYXMgSUFwcFNlcnZpY2VJbmZvKS5yZWdpc3RlclNlcnZpY2UobWV0YWRhdGEpO1xyXG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTZXJ2aWNlRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgcmVzdWx0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEFwcFNlcnZpY2VNZXRhZGF0YSkge1xyXG4gICAgICAgICAgICBjb25zdCBvdmVycmlkZGVuU2VydmljZVR5cGUgPSByZXN1bHQuc2VydmljZVR5cGU7XHJcbiAgICAgICAgICAgIGNvbnN0IG92ZXJyaWRkZW5JbmRleCA9IHRoaXMuX3NlcnZpY2VzLmZpbmRJbmRleChtID0+IG0uc2VydmljZVR5cGUgPT09IG92ZXJyaWRkZW5TZXJ2aWNlVHlwZSk7XHJcbiAgICAgICAgICAgIGlmIChvdmVycmlkZGVuSW5kZXggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2VydmljZXNbb3ZlcnJpZGRlbkluZGV4XSA9IG1ldGFkYXRhO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXJ2aWNlcy5wdXNoKG1ldGFkYXRhKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChyZXN1bHQpIHtcclxuICAgICAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5Ll9zZXJ2aWNlQ29udHJhY3RLZXksIGFwcFNlcnZpY2VJbmZvLCB0eXBlKTtcclxuICAgICAgICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5Ll9zZXJ2aWNlTWV0YWRhdGFLZXksIG1ldGFkYXRhLCB0eXBlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgc2VydmljZSBjb250cmFjdCBmcm9tIHRoZSBwcm92aWRlZCB0eXBlLCBpZiBwb3NzaWJsZS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0Fic3RyYWN0VHlwZX0gdHlwZSBUaGUgdHlwZSBhc3N1bWVkIHRvIGJlIGEgc2VydmljZSBjb250cmFjdCBvciBhIHNlcnZpY2UgdHlwZS5cclxuICAgICAqIEByZXR1cm5zIHsoQXBwU2VydmljZUluZm8gfCBudWxsKX0gVGhlIEFwcFNlcnZpY2VJbmZvIGluc3RhbmNlIG9yIG51bGwsIGlmIHRoZSB0eXBlIGlzIG5vdCBhIHNlcnZpY2UgY29udHJhY3QuXHJcbiAgICAgKiBAbWVtYmVyb2YgQXBwU2VydmljZUluZm9SZWdpc3RyeVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0U2VydmljZUNvbnRyYWN0KHR5cGU6IEFic3RyYWN0VHlwZSk6IEFwcFNlcnZpY2VJbmZvIHwgbnVsbCB7XHJcbiAgICAgICAgUmVxdWlyZXMuSGFzVmFsdWUodHlwZSwgJ3R5cGUnKTtcclxuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXRPd25NZXRhZGF0YShBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5Ll9zZXJ2aWNlQ29udHJhY3RLZXksIHR5cGUpIGFzIEFwcFNlcnZpY2VJbmZvIHx8IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIGEgdHlwZSBpcyBhIHNlcnZpY2UgY29udHJhY3QuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBYnN0cmFjdFR5cGV9IHR5cGUgVGhlIHR5cGUgYXNzdW1lZCB0byBiZSBhIHNlcnZpY2UgY29udHJhY3QuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqIEBtZW1iZXJvZiBBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpc1NlcnZpY2VDb250cmFjdCh0eXBlOiBBYnN0cmFjdFR5cGUpOiBib29sZWFuIHtcclxuICAgICAgICBSZXF1aXJlcy5IYXNWYWx1ZSh0eXBlLCAndHlwZScpO1xyXG4gICAgICAgIHJldHVybiBSZWZsZWN0Lmhhc093bk1ldGFkYXRhKEFwcFNlcnZpY2VJbmZvUmVnaXN0cnkuX3NlcnZpY2VDb250cmFjdEtleSwgdHlwZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBzZXJ2aWNlIG1ldGFkYXRhIGZyb20gdGhlIHByb3ZpZGVkIHR5cGUsIGlmIHBvc3NpYmxlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlfSB0eXBlIFRoZSB0eXBlIGFzc3VtZWQgdG8gYmUgYSBzZXJ2aWNlIHR5cGUuXHJcbiAgICAgKiBAcmV0dXJucyB7KEFwcFNlcnZpY2VNZXRhZGF0YSB8IG51bGwpfVxyXG4gICAgICogQG1lbWJlcm9mIEFwcFNlcnZpY2VJbmZvUmVnaXN0cnlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldFNlcnZpY2VNZXRhZGF0YSh0eXBlOiBBYnN0cmFjdFR5cGUpOiBBcHBTZXJ2aWNlTWV0YWRhdGE8YW55PiB8IG51bGwge1xyXG4gICAgICAgIFJlcXVpcmVzLkhhc1ZhbHVlKHR5cGUsICd0eXBlJyk7XHJcbiAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoQXBwU2VydmljZUluZm9SZWdpc3RyeS5fc2VydmljZU1ldGFkYXRhS2V5LCB0eXBlKSBhcyBBcHBTZXJ2aWNlTWV0YWRhdGE8YW55PiB8fCBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciBhIHR5cGUgaXMgYSBzZXJ2aWNlLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlfSB0eXBlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqIEBtZW1iZXJvZiBBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpc1NlcnZpY2UodHlwZTogQWJzdHJhY3RUeXBlKTogYm9vbGVhbiB7XHJcbiAgICAgICAgUmVxdWlyZXMuSGFzVmFsdWUodHlwZSwgJ3R5cGUnKTtcclxuICAgICAgICByZXR1cm4gUmVmbGVjdC5oYXNPd25NZXRhZGF0YShBcHBTZXJ2aWNlSW5mb1JlZ2lzdHJ5Ll9zZXJ2aWNlTWV0YWRhdGFLZXksIHR5cGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldENvbnRyYWN0T2ZTZXJ2aWNlKHR5cGU6IEFic3RyYWN0VHlwZSk6IEFwcFNlcnZpY2VJbmZvIHwgbnVsbCB7XHJcbiAgICAgICAgd2hpbGUgKHR5cGUpIHtcclxuICAgICAgICAgICAgY29uc3QgY29udHJhY3QgPSB0aGlzLmdldFNlcnZpY2VDb250cmFjdCh0eXBlKTtcclxuICAgICAgICAgICAgaWYgKGNvbnRyYWN0KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udHJhY3Q7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHR5cGVQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodHlwZS5wcm90b3R5cGUpO1xyXG4gICAgICAgICAgICB0eXBlID0gdHlwZVByb3RvdHlwZSAmJiB0eXBlUHJvdG90eXBlLmNvbnN0cnVjdG9yO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbn1cclxuIl19