This commit is contained in:
crusader 2017-08-05 22:09:04 +09:00
parent 347af46aa9
commit 04fa16b60d
77 changed files with 440 additions and 728 deletions

View File

@ -1,17 +1,13 @@
import {
ClassType,
} from '@loafer/core/constants/types';
import AnnotationConfigApplicationContext from '@loafer/context/annotation/AnnotationConfigApplicationContext'; import AnnotationConfigApplicationContext from '@loafer/context/annotation/AnnotationConfigApplicationContext';
import ApplicationStater from '@loafer/application/ApplicationStater'; import ApplicationStater from '@loafer/application/ApplicationStater';
class Application { class Application {
// private appContext: AppContext; // private appContext: AppContext;
private appClass: ClassType; private appClass: Class<any>;
// private appInstance: ApplicationStater; // private appInstance: ApplicationStater;
public constructor(clazz: ClassType) { public constructor(clazz: Class<any>) {
this.appClass = clazz; this.appClass = clazz;
} }
@ -23,7 +19,7 @@ class Application {
context.getPouch('entitlement'); context.getPouch('entitlement');
} }
public static run(clazz: ClassType): void { public static run(clazz: Class<any>): void {
new Application(clazz).run(); new Application(clazz).run();
} }
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -11,7 +7,7 @@ import {
} from '@loafer/context/decorator/Configuration'; } from '@loafer/context/decorator/Configuration';
export class ApplicationConfigurationAnnotation extends ConfigurationAnnotation { export class ApplicationConfigurationAnnotation extends ConfigurationAnnotation {
public constructor(qualifier?: PropertyType) { public constructor(qualifier?: QualifierName) {
super(qualifier); super(qualifier);
} }
public onClassDecorator = <TFunction extends Function>(target: TFunction): TFunction | void => { public onClassDecorator = <TFunction extends Function>(target: TFunction): TFunction | void => {

View File

@ -1,7 +1,3 @@
// import {
// PropertyType,
// } from '@loafer/core/constants/types';
// import EnvironmentCapable from '@loafer/core/env/EnvironmentCapable'; // import EnvironmentCapable from '@loafer/core/env/EnvironmentCapable';
// import PouchFactory from '@loafer/pouches/factory/PouchFactory'; // import PouchFactory from '@loafer/pouches/factory/PouchFactory';
@ -11,7 +7,7 @@
// import InjectCapablePouchFactory from '@loafer/pouches/factory/config/InjectCapablePouchFactory'; // import InjectCapablePouchFactory from '@loafer/pouches/factory/config/InjectCapablePouchFactory';
// export interface ApplicationContext extends EnvironmentCapable, ListablePouchFactory, HierarchicalPouchFactory { // export interface ApplicationContext extends EnvironmentCapable, ListablePouchFactory, HierarchicalPouchFactory {
// getId?(): PropertyType; // getId?(): Identity<T>;
// getApplicationName(): string; // getApplicationName(): string;
// getDisplayName(): string; // getDisplayName(): string;
// getParent?(): ApplicationContext; // getParent?(): ApplicationContext;

View File

@ -1,5 +1,5 @@
// import { // import {
// PropertyType, // Identity<T>,
// } from '@loafer/core/constants/types'; // } from '@loafer/core/constants/types';
// import ConfigurableEnvironment from '@loafer/core/env/ConfigurableEnvironment'; // import ConfigurableEnvironment from '@loafer/core/env/ConfigurableEnvironment';
// import ApplicationContext from '@loafer/context/ApplicationContext'; // import ApplicationContext from '@loafer/context/ApplicationContext';

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Assert, Assert,
} from '@loafer/core/util'; } from '@loafer/core/util';
@ -15,6 +10,11 @@ import {
PouchDefinitionRegistry, PouchDefinitionRegistry,
} from '@loafer/pouches/factory/support'; } from '@loafer/pouches/factory/support';
import {
AnnotatedGenericPouchDefinition,
} from '@loafer/pouches/factory/annotation';
import GenericApplicationContext from '@loafer/context/support/GenericApplicationContext'; import GenericApplicationContext from '@loafer/context/support/GenericApplicationContext';
@ -36,65 +36,75 @@ export class AnnotatedPouchDefinitionReader {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
} }
public getRegistry(): PouchDefinitionRegistry { /**
return this.registry; * Register one or more annotated classes to be processed.
} * <p>Calls to {@code register} are idempotent; adding the same
* annotated class more than once has no additional effect.
public setEnvironment(environment: Environment): void { * @param annotatedClasses one or more annotated classes,
this.conditionEvaluator = new ConditionEvaluator(this.registry, environment, null); * e.g. {@link Configuration @Configuration} classes
} */
public register(...annotatedClasses: Class<any>[]): void {
public setPouchNameGenerator(pouchNameGenerator: PouchNameGenerator): void {
this.pouchNameGenerator = (pouchNameGenerator !== null ? pouchNameGenerator : new AnnotationPouchNameGenerator());
}
public setScopeMetadataResolver(scopeMetadataResolver: ScopeMetadataResolver): void {
this.scopeMetadataResolver =
(scopeMetadataResolver !== null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
}
public register(...annotatedClasses: ClassType[]): void {
annotatedClasses.forEach(annotatedClass => { annotatedClasses.forEach(annotatedClass => {
this.registerPouch(annotatedClass); this.registerPouch(annotatedClass);
}); });
} }
/**
* Register a pouch from the given pouch class, deriving its metadata from
* class-declared annotations.
* @param annotatedClass the class of the pouch
*/
public registerPouch(annotatedClass: Class<any>): void {
this.doRegisterPouch(annotatedClass, null, null, null);
}
/**
* Register a pouch from the given pouch class, deriving its metadata from
* class-declared annotations.
* @param annotatedClass the class of the pouch
* @param instanceSupplier a callback for creating an instance of the pouch
* (may be {@code null})
* @param name an explicit name for the pouch
* @param qualifiers specific qualifier annotations to consider, if any,
* in addition to qualifiers at the pouch class level
* @param definitionCustomizers one or more callbacks for customizing the
* factory's {@link PouchDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0
*/
public doRegisterPouch<T>(annotatedClass: Class<T>, instanceSupplier: Supplier<T>, name: PouchName,
qualifiers: Class<Annotation>[], ...definitionCustomizers: PouchDefinitionCustomizer[]): void {
public registerPouch<TAnnotation extends Annotation>(annotatedClass: ClassType, name: PropertyType, ...qualifiers: TAnnotation[]): void {
let abd: AnnotatedGenericPouchDefinition = new AnnotatedGenericPouchDefinition(annotatedClass); let abd: AnnotatedGenericPouchDefinition = new AnnotatedGenericPouchDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return; return;
} }
abd.setInstanceSupplier(instanceSupplier);
let scopeMetadata: ScopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); let scopeMetadata: ScopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName()); abd.setScope(scopeMetadata.getScopeName());
let pouchName: string = (name !== null ? name : this.pouchNameGenerator.generatePouchName(abd, this.registry)); let pouchName: PouchName = (name != null ? name : this.pouchNameGenerator.generatePouchName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers !== undefined) { if (qualifiers != null) {
qualifiers.forEach((qualifier, index, array) => { qualifiers.forEach((qualifier, index) => {
if (Primary.class === qualifier) { if (Primary.class === qualifier) {
abd.setPrimary(true); abd.setPrimary(true);
} else if (Lazy.class === qualifier) { }
else if (Lazy.class === qualifier) {
abd.setLazyInit(true); abd.setLazyInit(true);
} else { }
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier)); abd.addQualifier(new AutowireCandidateQualifier(qualifier));
} }
}); });
} }
definitionCustomizers.forEach((customizer) => {
customizer.customize(abd);
});
let definitionHolder: PouchDefinitionHolder = new PouchDefinitionHolder(abd, pouchName); let definitionHolder: PouchDefinitionHolder = new PouchDefinitionHolder(abd, pouchName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
PouchDefinitionReaderUtils.registerPouchDefinition(definitionHolder, this.registry); PouchDefinitionReaderUtils.registerPouchDefinition(definitionHolder, this.registry);
} }
private static getOrCreateEnvironment(registry: PouchDefinitionRegistry): Environment {
Assert.notNull(registry, 'PouchDefinitionRegistry must not be null');
if (registry instanceof EnvironmentCapable) {
return (<EnvironmentCapable>registry).getEnvironment();
}
return new StandardEnvironment();
}
} }
export default AnnotatedPouchDefinitionReader; export default AnnotatedPouchDefinitionReader;

View File

@ -1,7 +1,3 @@
import {
ClassType,
} from '@loafer/core/constants/types';
import { import {
Assert, Assert,
} from '@loafer/core/util'; } from '@loafer/core/util';
@ -9,13 +5,10 @@ import {
import GenericApplicationContext from '@loafer/context/support/GenericApplicationContext'; import GenericApplicationContext from '@loafer/context/support/GenericApplicationContext';
import AnnotatedPouchDefinitionReader from '@loafer/context/annotation/AnnotatedPouchDefinitionReader'; import AnnotatedPouchDefinitionReader from '@loafer/context/annotation/AnnotatedPouchDefinitionReader';
export class AnnotationConfigApplicationContext extends GenericApplicationContext { export class AnnotationConfigApplicationContext extends GenericApplicationContext {
private readonly reader: AnnotatedPouchDefinitionReader; private readonly reader: AnnotatedPouchDefinitionReader;
public register(...annotatedClasses: Class<any>[]): void {
public register(...annotatedClasses: ClassType[]): void {
Assert.notEmpty(annotatedClasses, 'At least one annotated class must be specified'); Assert.notEmpty(annotatedClasses, 'At least one annotated class must be specified');
this.reader.register(annotatedClasses); this.reader.register(annotatedClasses);
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -11,7 +7,7 @@ import {
} from '@loafer/pouches/decorator/Injectable'; } from '@loafer/pouches/decorator/Injectable';
export class ConfigurationAnnotation extends InjectableAnnotation { export class ConfigurationAnnotation extends InjectableAnnotation {
public constructor(qualifier?: PropertyType) { public constructor(qualifier?: QualifierName) {
super(qualifier); super(qualifier);
} }
public onClassDecorator = <TFunction extends Function>(target: TFunction): TFunction | void => { public onClassDecorator = <TFunction extends Function>(target: TFunction): TFunction | void => {

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -10,20 +5,20 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export interface PouchConfig { export interface PouchConfig {
qualifier?: PropertyType; qualifier?: QualifierName;
type?: ClassType; type?: Class<any>;
} }
export class PouchAnnotation extends Annotation { export class PouchAnnotation extends Annotation {
private readonly Qualifier: PropertyType; private readonly Qualifier: QualifierName;
private readonly Type: ClassType; private readonly Type: Class<any>;
public constructor(config: PouchConfig = {}) { public constructor(config: PouchConfig = {}) {
super(); super();
this.Qualifier = config.qualifier; this.Qualifier = config.qualifier;
this.Type = config.type; this.Type = config.type;
} }
public onMethodDecorator = <T>(target: Object, propertyKey: PropertyType, public onMethodDecorator = <T>(target: Object, propertyKey: Identity<T>,
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => { descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => {
console.log('Pouch'); console.log('Pouch');
} }

View File

@ -1,12 +1,8 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
export interface AliasRegistry { export interface AliasRegistry {
registerAlias(name: PropertyType, alias: PropertyType): void; registerAlias(name: PouchName, alias: PouchName): void;
removeAlias(alias: PropertyType): void; removeAlias(alias: PouchName): void;
isAlias(name: PropertyType): boolean; isAlias(name: PouchName): boolean;
getAliases(name: PropertyType): PropertyType[]; getAliases(name: PouchName): PouchName[];
} }
export default AliasRegistry; export default AliasRegistry;

View File

@ -0,0 +1,5 @@
export interface AttributeAccessor {
}
export default AttributeAccessor;

View File

@ -0,0 +1,8 @@
import {
AttributeAccessor,
} from '@loafer/core';
export abstract class AttributeAccessorSupport implements AttributeAccessor {
}
export default AttributeAccessorSupport;

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import Executable from '@loafer/core/reflect/Executable'; import Executable from '@loafer/core/reflect/Executable';
import Parameter from '@loafer/core/reflect/Parameter'; import Parameter from '@loafer/core/reflect/Parameter';
import Method from '@loafer/core/reflect/Method'; import Method from '@loafer/core/reflect/Method';

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import AliasRegistry from '@loafer/core/AliasRegistry'; import AliasRegistry from '@loafer/core/AliasRegistry';
export class SimpleAliasRegistry implements AliasRegistry { export class SimpleAliasRegistry implements AliasRegistry {

View File

@ -1,18 +1,9 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import {
Class,
} from '@loafer/core/reflect';
export interface Annotation { export interface Annotation {
onClassDecorator?: <TFunction extends Function>(target: TFunction) => TFunction | void; onClassDecorator?: <TFunction extends Function>(target: TFunction) => TFunction | void;
onPropertyDecorator?: (target: Object, propertyKey: PropertyType) => void; onPropertyDecorator?: (target: Object, propertyKey: PropertyName) => void;
onMethodDecorator?: <T>(target: Object, propertyKey: PropertyType, onMethodDecorator?: <T>(target: Object, propertyKey: PropertyName,
descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void; descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
onParameterDecorator?: (target: Object, propertyKey: PropertyType, parameterIndex: number) => void; onParameterDecorator?: (target: Object, propertyKey: PropertyName, parameterIndex: number) => void;
} }
export abstract class Annotation { export abstract class Annotation {

View File

@ -1,3 +0,0 @@
export type Construtorable<T> = {new(...args: any[]): T};
export type ClassType = Object;
export type PropertyType = string | symbol;

View File

@ -1,15 +1,11 @@
import {
ClassType,
Construtorable,
} from '@loafer/core/constants/types';
import * as ReflectConstants from '@loafer/core/constants/reflect'; import * as ReflectConstants from '@loafer/core/constants/reflect';
import Reflection from '@loafer/core/reflect/Reflection'; import Reflection from '@loafer/core/reflect/Reflection';
import Class from '@loafer/core/reflect/Class'; import Clazz from '@loafer/core/reflect/Clazz';
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
import DecoratorType from './DecoratorType'; import DecoratorType from './DecoratorType';
export class Decorator { export class Decorator {
public static create = (AnnotationType: Construtorable<Annotation>) => { public static create = (AnnotationType: Class<Annotation>) => {
return (...handlerArgs: any[]) => { return (...handlerArgs: any[]) => {
let annotation: Annotation = new AnnotationType(...handlerArgs); let annotation: Annotation = new AnnotationType(...handlerArgs);
@ -22,7 +18,7 @@ export class Decorator {
reflection = new Reflection(type); reflection = new Reflection(type);
Reflect.defineMetadata(ReflectConstants.REFLECT_META, reflection, type); Reflect.defineMetadata(ReflectConstants.REFLECT_META, reflection, type);
} }
let clazz: Class = reflection.getClass(); let clazz: Clazz = reflection.getClass();
switch(decoratorType) { switch(decoratorType) {
case DecoratorType.CLASS: case DecoratorType.CLASS:
@ -43,7 +39,7 @@ export class Decorator {
}; };
} }
public static get = (targetType: ClassType) => { public static get = (targetType: Class<any>) => {
let reflection: Reflection = Reflect.getMetadata(ReflectConstants.REFLECT_META, targetType); let reflection: Reflection = Reflect.getMetadata(ReflectConstants.REFLECT_META, targetType);
if (undefined === reflection) { if (undefined === reflection) {
return undefined; return undefined;

View File

@ -1,5 +1,5 @@
export enum DecoratorType { export enum DecoratorType {
CLASS = 'Class', CLASS = 'Clazz',
PROPERTY = 'Property', PROPERTY = 'Property',
METHOD = 'Method', METHOD = 'Method',
PARAMETER = 'Parameter', PARAMETER = 'Parameter',

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import Environment from '@loafer/core/env/Environment'; import Environment from '@loafer/core/env/Environment';
export interface ConfigurableEnvironment extends Environment { export interface ConfigurableEnvironment extends Environment {

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import PropertyResolver from '@loafer/core/env/PropertyResolver'; import PropertyResolver from '@loafer/core/env/PropertyResolver';
export interface Environment extends PropertyResolver { export interface Environment extends PropertyResolver {

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
export interface PropertyResolver { export interface PropertyResolver {
} }

View File

@ -1,3 +1,6 @@
export * from './AliasRegistry'; export * from './AliasRegistry';
export * from './AttributeAccessor';
export * from './AttributeAccessorSupport';
export * from './NestedRuntimeException'; export * from './NestedRuntimeException';
export * from './SimpleAliasRegistry'; export * from './SimpleAliasRegistry';

View File

@ -1,15 +1,11 @@
import {
ClassType,
} from '@loafer/core/constants/types';
export abstract class AnnotatedElement { export abstract class AnnotatedElement {
private _annotationMap: Map<ClassType, any>; private _annotationMap: Map<Class<any>, any>;
protected constructor() { protected constructor() {
this._annotationMap = new Map(); this._annotationMap = new Map();
} }
public getDeclaredAnnotation(type: ClassType): any { public getDeclaredAnnotation(type: Class<any>): any {
return this._annotationMap.get(type); return this._annotationMap.get(type);
} }
public getDeclaredAnnotations(): IterableIterator<any> { public getDeclaredAnnotations(): IterableIterator<any> {
@ -17,15 +13,15 @@ export abstract class AnnotatedElement {
} }
public addAnnotation(annotation: any): void { public addAnnotation(annotation: any): void {
const type: ClassType = Object.getPrototypeOf(annotation); const type: Class<any> = Object.getPrototypeOf(annotation);
this._annotationMap.set(type, annotation); this._annotationMap.set(type, annotation);
} }
public hasAnnotation(type: ClassType): boolean { public hasAnnotation(type: Class<any>): boolean {
return this._annotationMap.has(type); return this._annotationMap.has(type);
} }
// public abstract getAnnotation(type: ClassType): any; // public abstract getAnnotation(type: Class<any>): any;
// public abstract getAnnotations(): IterableIterator<any>; // public abstract getAnnotations(): IterableIterator<any>;
} }

View File

@ -1,22 +1,17 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import AnnotatedElement from './AnnotatedElement'; import AnnotatedElement from './AnnotatedElement';
import Constructor from './Constructor'; import Constructor from './Constructor';
import Property from './Property'; import Property from './Property';
import Method from './Method'; import Method from './Method';
export class Class extends AnnotatedElement { export class Clazz extends AnnotatedElement {
private _type: ClassType; private _type: Class<any>;
private _name: PropertyType; private _name: PropertyName;
private _constructor: Constructor; private _constructor: Constructor;
private _properties: Map<PropertyType, Property>; private _properties: Map<PropertyName, Property>;
private _methodes: Map<PropertyType, Method>; private _methodes: Map<PropertyName, Method>;
public constructor(type: ClassType, parameterTypes: ClassType[]) { public constructor(type: Class<any>, parameterTypes: Class<any>[]) {
super(); super();
this._type = type; this._type = type;
this._name = this._type.constructor.name; this._name = this._type.constructor.name;
@ -25,11 +20,11 @@ export class Class extends AnnotatedElement {
this._methodes = new Map(); this._methodes = new Map();
} }
public get Type(): ClassType { public get Type(): Class<any> {
return this._type; return this._type;
} }
public get Name(): PropertyType { public get Name(): PropertyName {
return this._name; return this._name;
} }
@ -37,39 +32,39 @@ export class Class extends AnnotatedElement {
return this._constructor; return this._constructor;
} }
public addProperty(propertyKey: PropertyType, type: ClassType): Property { public addProperty(propertyKey: PropertyName, type: Class<any>): Property {
if (this._properties.has(propertyKey)) { if (this._properties.has(propertyKey)) {
throw new Error(`Property[${propertyKey}:${type.constructor.name}] on Class[${this._name}] is exist already`); throw new Error(`Property[${propertyKey}:${type.constructor.name}] on Clazz[${this._name}] is exist already`);
} }
let proerty = new Property(type, propertyKey); let proerty = new Property(type, propertyKey);
this._properties.set(propertyKey, proerty); this._properties.set(propertyKey, proerty);
return proerty; return proerty;
} }
public getProperty(propertyKey: PropertyType): Property { public getProperty(propertyKey: PropertyName): Property {
return this._properties.get(propertyKey); return this._properties.get(propertyKey);
} }
public hasProperty(propertyKey: PropertyType): boolean { public hasProperty(propertyKey: PropertyName): boolean {
return this._properties.has(propertyKey); return this._properties.has(propertyKey);
} }
public addMethod(propertyKey: PropertyType, parameterTypes: ClassType[], returnType: ClassType): Method { public addMethod(propertyKey: PropertyName, parameterTypes: Class<any>[], returnType: Class<any>): Method {
if (this._methodes.has(propertyKey)) { if (this._methodes.has(propertyKey)) {
throw new Error(`Method[${propertyKey}:${returnType.constructor.name}] on Class[${this._name}] is exist already`); throw new Error(`Method[${propertyKey}:${returnType.constructor.name}] on Clazz[${this._name}] is exist already`);
} }
let method = new Method(propertyKey, parameterTypes, returnType); let method = new Method(propertyKey, parameterTypes, returnType);
this._methodes.set(propertyKey, method); this._methodes.set(propertyKey, method);
return method; return method;
} }
public getMethod(propertyKey: PropertyType): Method { public getMethod(propertyKey: PropertyName): Method {
return this._methodes.get(propertyKey); return this._methodes.get(propertyKey);
} }
public hasMethod(propertyKey: PropertyType): boolean { public hasMethod(propertyKey: PropertyName): boolean {
return this._methodes.has(propertyKey); return this._methodes.has(propertyKey);
} }
} }
export default Class; export default Clazz;

View File

@ -1,13 +1,8 @@
import {
ClassType,
} from '@loafer/core/constants/types';
import Executable from '@loafer/core/reflect/Executable'; import Executable from '@loafer/core/reflect/Executable';
export class Constructor extends Executable { export class Constructor extends Executable {
public constructor(parameterTypes: ClassType[]) { public constructor(parameterTypes: Class<any>[]) {
super(parameterTypes); super(parameterTypes);
} }
} }

View File

@ -1,14 +1,10 @@
import {
ClassType,
} from '@loafer/core/constants/types';
import AnnotatedElement from './AnnotatedElement'; import AnnotatedElement from './AnnotatedElement';
import Parameter from '@loafer/core/reflect/Parameter'; import Parameter from '@loafer/core/reflect/Parameter';
export abstract class Executable extends AnnotatedElement { export abstract class Executable extends AnnotatedElement {
protected _parameters: Parameter[]; protected _parameters: Parameter[];
public constructor(parameterTypes: ClassType[]) { public constructor(parameterTypes: Class<any>[]) {
super(); super();
this._parameters = []; this._parameters = [];

View File

@ -1,29 +1,24 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import Executable from '@loafer/core/reflect/Executable'; import Executable from '@loafer/core/reflect/Executable';
export class Method extends Executable { export class Method extends Executable {
private _name: PropertyType; private _name: PropertyName;
private _returnType: ClassType; private _returnType: Class<any>;
public constructor(name: PropertyType, parameterTypes: ClassType[], returnType: ClassType) { public constructor(name: PropertyName, parameterTypes: Class<any>[], returnType: Class<any>) {
super(parameterTypes); super(parameterTypes);
this._name = name; this._name = name;
this._returnType = returnType; this._returnType = returnType;
} }
public get Name(): PropertyType { public get Name(): PropertyName {
return this._name; return this._name;
} }
public get ReturnType(): ClassType { public get ReturnType(): Class<any> {
return this._returnType; return this._returnType;
} }
public set ReturnType(returnType: ClassType) { public set ReturnType(returnType: Class<any>) {
this._returnType = returnType; this._returnType = returnType;
} }

View File

@ -1,22 +1,18 @@
import {
ClassType,
} from '@loafer/core/constants/types';
import AnnotatedElement from './AnnotatedElement'; import AnnotatedElement from './AnnotatedElement';
import Constructor from './Constructor'; import Constructor from './Constructor';
export class Parameter extends AnnotatedElement { export class Parameter extends AnnotatedElement {
private _type: ClassType; private _type: Class<any>;
private _index: number; private _index: number;
public constructor(type: ClassType, index: number) { public constructor(type: Class<any>, index: number) {
super(); super();
this._type = type; this._type = type;
this._index = index; this._index = index;
} }
public get Type(): ClassType { public get Type(): Class<any> {
return this._type; return this._type;
} }

View File

@ -1,27 +1,22 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import AnnotatedElement from './AnnotatedElement'; import AnnotatedElement from './AnnotatedElement';
import Constructor from './Constructor'; import Constructor from './Constructor';
export class Property extends AnnotatedElement { export class Property extends AnnotatedElement {
private _type: ClassType; private _type: Class<any>;
private _name: PropertyType; private _name: PropertyName;
public constructor(type: ClassType, name: PropertyType) { public constructor(type: Class<any>, name: PropertyName) {
super(); super();
this._type = type; this._type = type;
this._name = name; this._name = name;
} }
public get Name(): PropertyType { public get Name(): PropertyName {
return this._name; return this._name;
} }
public get Type(): ClassType { public get Type(): Class<any> {
return this._type; return this._type;
} }
} }

View File

@ -1,26 +1,21 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import * as ReflectConstants from '@loafer/core/constants/reflect'; import * as ReflectConstants from '@loafer/core/constants/reflect';
import AnnotatedElement from './AnnotatedElement'; import AnnotatedElement from './AnnotatedElement';
import Class from './Class'; import Clazz from './Clazz';
export class Reflection { export class Reflection {
private _clazz: Class; private _clazz: Clazz;
public constructor(type: ClassType) { public constructor(type: Class<any>) {
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, type.constructor); let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, type.constructor);
this._clazz = new Class(type, this.convertParamTypes(parameterTypes)); this._clazz = new Clazz(type, this.convertParamTypes(parameterTypes));
} }
/** /**
* getClass * getClass
*/ */
public getClass(): Class { public getClass(): Clazz {
return this._clazz; return this._clazz;
} }
@ -34,7 +29,7 @@ export class Reflection {
this._clazz.addAnnotation(annotation); this._clazz.addAnnotation(annotation);
} }
public addPropertyAnnotation(annotation: any, propertyKey: PropertyType): void { public addPropertyAnnotation(annotation: any, propertyKey: PropertyName): void {
let propertyType: any = Reflect.getMetadata(ReflectConstants.DESIGN_TYPE, this._clazz.Type, propertyKey); let propertyType: any = Reflect.getMetadata(ReflectConstants.DESIGN_TYPE, this._clazz.Type, propertyKey);
let property = this._clazz.getProperty(propertyKey); let property = this._clazz.getProperty(propertyKey);
@ -49,7 +44,7 @@ export class Reflection {
property.addAnnotation(annotation); property.addAnnotation(annotation);
} }
public addMethodAnnotation(annotation: any, propertyKey: PropertyType): void { public addMethodAnnotation(annotation: any, propertyKey: PropertyName): void {
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type, propertyKey); let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type, propertyKey);
let returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey); let returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey);
@ -65,7 +60,7 @@ export class Reflection {
method.addAnnotation(annotation); method.addAnnotation(annotation);
} }
public addParameterAnnotation(annotation: any, propertyKey: PropertyType, parameterIndex: number): void { public addParameterAnnotation(annotation: any, propertyKey: PropertyName, parameterIndex: number): void {
let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type, propertyKey); let parameterTypes: any[] = Reflect.getMetadata(ReflectConstants.DESIGN_PARAMTYPES, this._clazz.Type, propertyKey);
let returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey); let returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey);
@ -85,7 +80,7 @@ throw new Error(`Cannot apply @${name} decorator multiple times on Parameter[${t
} }
private validateAnnotation(annotation: any, element: AnnotatedElement): {valid: boolean, name: string} { private validateAnnotation(annotation: any, element: AnnotatedElement): {valid: boolean, name: string} {
const annotationType: ClassType = Object.getPrototypeOf(annotation); const annotationType: Class<any> = Object.getPrototypeOf(annotation);
const name: string = annotationType.constructor.name; const name: string = annotationType.constructor.name;
if (element.hasAnnotation(annotationType)) { if (element.hasAnnotation(annotationType)) {
@ -94,8 +89,8 @@ throw new Error(`Cannot apply @${name} decorator multiple times on Parameter[${t
return {valid: true, name: name}; return {valid: true, name: name};
} }
private convertParamTypes(parameterTypes: any[]): ClassType[] { private convertParamTypes(parameterTypes: any[]): Class<any>[] {
let returnTypes: ClassType[] = []; let returnTypes: Class<any>[] = [];
parameterTypes.forEach((currentValue, index, array) => { parameterTypes.forEach((currentValue, index, array) => {
returnTypes.push(currentValue.prototype); returnTypes.push(currentValue.prototype);
}); });

View File

@ -1,5 +1,5 @@
export * from './AnnotatedElement'; export * from './AnnotatedElement';
export * from './Class'; export * from './Clazz';
export * from './Constructor'; export * from './Constructor';
export * from './Executable'; export * from './Executable';
export * from './Method'; export * from './Method';

View File

@ -0,0 +1,4 @@
export interface AnnotatedTypeMetadata {
}
export default AnnotatedTypeMetadata;

View File

@ -0,0 +1,9 @@
import {
AnnotatedTypeMetadata,
ClassMetadata,
} from '@loafer/core/type';
export interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {
}
export default AnnotationMetadata;

View File

@ -0,0 +1,4 @@
export interface ClassMetadata {
}
export default ClassMetadata;

View File

@ -0,0 +1,25 @@
import {
AnnotationMetadata,
StandardClassMetadata,
} from '@loafer/core/type';
export class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata {
/**
* Create a new {@link StandardAnnotationMetadata} wrapper for the given Class,
* providing the option to return any nested annotations or annotation arrays in the
* form of {@link org.springframework.core.annotation.AnnotationAttributes} instead
* of actual {@link Annotation} instances.
* @param introspectedClass the Class to introspect
* @param nestedAnnotationsAsMap return nested annotations and annotation arrays as
* {@link org.springframework.core.annotation.AnnotationAttributes} for compatibility
* with ASM-based {@link AnnotationMetadata} implementations
* @since 3.1.1
*/
public constructor(introspectedClass: Class<any>, nestedAnnotationsAsMap: boolean) {
super(introspectedClass);
this.annotations = introspectedClass.getAnnotations();
this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
}
}
export default StandardAnnotationMetadata;

View File

@ -0,0 +1,8 @@
import {
ClassMetadata,
} from '@loafer/core/type';
export class StandardClassMetadata extends ClassMetadata {
}
export default StandardClassMetadata;

View File

@ -0,0 +1,5 @@
export * from './AnnotatedTypeMetadata';
export * from './AnnotationMetadata';
export * from './ClassMetadata';
export * from './StandardAnnotationMetadata';
export * from './StandardClassMetadata';

View File

@ -1,7 +1,3 @@
import {
ClassType,
} from '@loafer/core/constants/types';
import { import {
IllegalStateException, IllegalStateException,
IllegalArgumentException, IllegalArgumentException,
@ -94,14 +90,14 @@ export abstract class Assert {
} }
} }
public static isInstanceOf(type: ClassType, obj: any, message: string = ''): void { public static isInstanceOf(type: Class<any>, obj: any, message: string = ''): void {
Assert.notNull(type, 'Type to check against must not be null'); Assert.notNull(type, 'Type to check against must not be null');
if (!(obj instanceof type.constructor)) { if (!(obj instanceof type.constructor)) {
Assert.instanceCheckFailed(type, obj, message); Assert.instanceCheckFailed(type, obj, message);
} }
} }
private static instanceCheckFailed(type: ClassType, obj: any, message: string): void { private static instanceCheckFailed(type: Class<any>, obj: any, message: string): void {
let className = (obj !== undefined && obj !== null ? Object.getPrototypeOf(obj).constructor.name : 'null'); let className = (obj !== undefined && obj !== null ? Object.getPrototypeOf(obj).constructor.name : 'null');
let result = ''; let result = '';
let defaultMessage = true; let defaultMessage = true;

View File

@ -0,0 +1,64 @@
export abstract class ObjectUtils {
/**
* Determine if the given objects are equal, returning {@code true} if
* both are {@code null} or {@code false} if only one is {@code null}.
* <p>Compares arrays with {@code Arrays.equals}, performing an equality
* check based on the array elements rather than the array reference.
* @param o1 first Object to compare
* @param o2 second Object to compare
* @return whether the given objects are equal
* @see Object#equals(Object)
* @see java.util.Arrays#equals
*/
public static nullSafeEquals(o1: any, o2: any): boolean {
if (o1 === o2) {
return true;
}
if (o1 === undefined || o2 === undefined) {
return false;
}
if (o1 == null || o2 == null) {
return false;
}
if (Array.isArray(o1) && Array.isArray(o2)) {
return ObjectUtils.arrayEquals(o1, o2);
}
return false;
}
/**
* Compare the given arrays with {@code Arrays.equals}, performing an equality
* check based on the array elements rather than the array reference.
* @param o1 first array to compare
* @param o2 second array to compare
* @return whether the given objects are equal
* @see #nullSafeEquals(Object, Object)
* @see java.util.Arrays#equals
*/
private static arrayEquals(o1: any, o2: any): boolean {
if (!Array.isArray(o1) || !Array.isArray(o2)) {
return false;
}
if (o1 === o2) {
return true;
}
const arr1 = <Array<any>>o1;
const arr2 = <Array<any>>o2;
if (arr1.length !== arr2.length) {
return false;
}
arr1.forEach((value, index) => {
if (value !== arr2[index]) {
return false;
}
});
return true;
}
}
export default ObjectUtils;

View File

@ -0,0 +1,6 @@
export abstract class TypeUtils {
}
export default TypeUtils;

View File

@ -1,2 +1,5 @@
export * from './Assert'; export * from './Assert';
export * from './ObjectUtils';
export * from './StringUtils'; export * from './StringUtils';
export * from './TypeUtils';

7
src/ts/@loafer/globals.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
declare type Class<T> = {new(...args: any[]): T};
declare type Interface = Object;
declare type Identity<T> = T | symbol;
declare type PropertyName = Identity<string>;
declare type QualifierName = Identity<string>;
declare type PouchName = Identity<string>;
declare type ValueName = Identity<string>;

View File

@ -0,0 +1,20 @@
export interface Mergeable {
/**
* Is merging enabled for this particular instance?
*/
isMergeEnabled(): boolean;
/**
* Merge the current value set with that of the supplied object.
* <p>The supplied object is considered the parent, and values in
* the callee's value set must override those of the supplied object.
* @param parent the object to merge with
* @return the result of the merge operation
* @throws IllegalArgumentException if the supplied parent is {@code null}
* @exception IllegalStateException if merging is not enabled for this instance
* (i.e. {@code mergeEnabled} equals {@code false}).
*/
merge(parent: any): any;
}
export default Mergeable;

View File

@ -0,0 +1,14 @@
import {
AttributeAccessorSupport,
} from '@loafer/core';
import {
PouchMetadataElement,
} from '@loafer/pouches';
export class PouchMetadataAttributeAccessor extends AttributeAccessorSupport implements PouchMetadataElement {
}
export default PouchMetadataAttributeAccessor;

View File

@ -1,9 +1,4 @@
export interface PouchMetadataElement { export interface PouchMetadataElement {
/**
* Return the configuration source {@code Object} for this metadata element
* (may be {@code null}).
*/
getSource(): any;
} }
export default PouchMetadataElement; export default PouchMetadataElement;

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -10,15 +5,15 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export interface InjectConfig { export interface InjectConfig {
qualifier?: PropertyType; qualifier?: QualifierName;
required?: boolean; required?: boolean;
type?: ClassType; type?: Class<any>;
} }
export class InjectAnnotation extends Annotation { export class InjectAnnotation extends Annotation {
private readonly Qualifier: PropertyType; private readonly Qualifier: QualifierName;
private readonly Required: boolean; private readonly Required: boolean;
private readonly Type: ClassType; private readonly Type: Class<any>;
public constructor(config: InjectConfig = {}) { public constructor(config: InjectConfig = {}) {
super(); super();
@ -27,14 +22,14 @@ export class InjectAnnotation extends Annotation {
this.Type = config.type; this.Type = config.type;
} }
public onPropertyDecorator = (target: Object, propertyKey: PropertyType): void => { public onPropertyDecorator = (target: Object, propertyKey: PropertyName): void => {
console.log('Inject'); console.log('Inject');
} }
public onMethodDecorator = <T>(target: Object, propertyKey: PropertyType, public onMethodDecorator = <T>(target: Object, propertyKey: PropertyName,
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => { descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => {
console.log('Inject'); console.log('Inject');
} }
public onParameterDecorator = (target: Object, propertyKey: PropertyType, parameterIndex: number): void => { public onParameterDecorator = (target: Object, propertyKey: PropertyName, parameterIndex: number): void => {
console.log('Inject'); console.log('Inject');
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -9,9 +5,9 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export class InjectableAnnotation extends Annotation { export class InjectableAnnotation extends Annotation {
private readonly Qualifier: PropertyType; private readonly Qualifier: QualifierName;
public constructor(qualifier?: PropertyType) { public constructor(qualifier?: QualifierName) {
super(); super();
this.Qualifier = qualifier; this.Qualifier = qualifier;
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -9,7 +5,7 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export class PostConstructAnnotation extends Annotation { export class PostConstructAnnotation extends Annotation {
public onMethodDecorator = <T>(target: Object, propertyKey: PropertyType, public onMethodDecorator = <T>(target: Object, propertyKey: PropertyName,
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => { descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => {
console.log('PostConstruct'); console.log('PostConstruct');
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -9,7 +5,7 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export class PreDestroyAnnotation extends Annotation { export class PreDestroyAnnotation extends Annotation {
public onMethodDecorator = <T>(target: Object, propertyKey: PropertyType, public onMethodDecorator = <T>(target: Object, propertyKey: PropertyName,
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => { descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => {
console.log('PreDestroy'); console.log('PreDestroy');
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -9,9 +5,9 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export class ScopeAnnotation extends Annotation { export class ScopeAnnotation extends Annotation {
private readonly Qualifier: PropertyType; private readonly Qualifier: QualifierName;
public constructor(qualifier?: PropertyType) { public constructor(qualifier?: QualifierName) {
super(); super();
this.Qualifier = qualifier; this.Qualifier = qualifier;
} }

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Decorator, Decorator,
} from '@loafer/core/decorator'; } from '@loafer/core/decorator';
@ -10,17 +5,17 @@ import {
import Annotation from '@loafer/core/annotation/Annotation'; import Annotation from '@loafer/core/annotation/Annotation';
export class ValueAnnotation extends Annotation { export class ValueAnnotation extends Annotation {
private readonly Value: PropertyType; private readonly Value: ValueName;
public constructor(value: PropertyType) { public constructor(value: ValueName) {
super(); super();
this.Value = value; this.Value = value;
} }
public onPropertyDecorator = (target: Object, propertyKey: PropertyType): void => { public onPropertyDecorator = (target: Object, propertyKey: PropertyName): void => {
console.log('Value'); console.log('Value');
} }
public onParameterDecorator = (target: Object, propertyKey: PropertyType, parameterIndex: number): void => { public onParameterDecorator = (target: Object, propertyKey: PropertyName, parameterIndex: number): void => {
console.log('Value'); console.log('Value');
} }

View File

@ -1,7 +1,3 @@
import {
ClassType,
} from '@loafer/core/constants/types';
export interface FactoryPouch<T> { export interface FactoryPouch<T> {
} }

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import PouchFactory from '@loafer/pouches/factory/PouchFactory'; import PouchFactory from '@loafer/pouches/factory/PouchFactory';
export interface ListablePouchFactory extends PouchFactory { export interface ListablePouchFactory extends PouchFactory {

View File

@ -1,11 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import {
Class,
} from '@loafer/core/reflect';
export interface PouchFactory { export interface PouchFactory {

View File

@ -0,0 +1,26 @@
import {
AnnotationMetadata,
} from '@loafer/core/type';
import {
GenericPouchDefinition,
} from '@loafer/pouches/factory/support';
import {
AnnotatedPouchDefinition,
} from '@loafer/pouches/factory/annotation';
export class AnnotatedGenericPouchDefinition extends GenericPouchDefinition implements AnnotatedPouchDefinition {
private readonly metadata: AnnotationMetadata;
public constructor(pouchClass: Class<any>) {
super();
this.PouchClass = pouchClass;
this.metadata = new StandardAnnotationMetadata(pouchClass, true);
}
}
export default AnnotatedGenericPouchDefinition;

View File

@ -0,0 +1,11 @@
import {
PouchDefinition,
} from '@loafer/pouches/factory/config';
export interface AnnotatedPouchDefinition extends PouchDefinition {
}
export default AnnotatedPouchDefinition;

View File

@ -0,0 +1,2 @@
export * from './AnnotatedPouchDefinition';
export * from './AnnotatedGenericPouchDefinition';

View File

@ -1,7 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import PouchFactory from '@loafer/pouches/factory/PouchFactory'; import PouchFactory from '@loafer/pouches/factory/PouchFactory';
export interface ConfigurableListablePouchFactory { export interface ConfigurableListablePouchFactory {

View File

@ -1,7 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import PouchFactory from '@loafer/pouches/factory/PouchFactory'; import PouchFactory from '@loafer/pouches/factory/PouchFactory';
import HierarchicalPouchFactory from '@loafer/pouches/factory/HierarchicalPouchFactory'; import HierarchicalPouchFactory from '@loafer/pouches/factory/HierarchicalPouchFactory';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition'; import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';

View File

@ -1,13 +1,11 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import { import {
Assert, Assert,
ObjectUtils,
TypeUtils,
} from '@loafer/core/util'; } from '@loafer/core/util';
import { import {
Mergeable,
PouchMetadataElement, PouchMetadataElement,
} from '@loafer/pouches'; } from '@loafer/pouches';
@ -22,9 +20,6 @@ import {
SingletonPouchRegistry, SingletonPouchRegistry,
} from '@loafer/pouches/factory/config'; } from '@loafer/pouches/factory/config';
export class ConstructorArgumentValues { export class ConstructorArgumentValues {
private readonly indexedArgumentValues: Map<number, ValueHolder> = new Map(); private readonly indexedArgumentValues: Map<number, ValueHolder> = new Map();
private readonly genericArgumentValues: ValueHolder[] = []; private readonly genericArgumentValues: ValueHolder[] = [];
@ -34,311 +29,10 @@ export class ConstructorArgumentValues {
* @param original the ConstructorArgumentValues to copy * @param original the ConstructorArgumentValues to copy
*/ */
public constructor(original?: ConstructorArgumentValues) { public constructor(original?: ConstructorArgumentValues) {
this.addArgumentValues(original); //
} }
/**
* Copy all given argument values into this object, using separate holder
* instances to keep the values independent from the original object.
* <p>Note: Identical ValueHolder instances will only be registered once,
* to allow for merging and re-merging of argument value definitions. Distinct
* ValueHolder instances carrying the same content are of course allowed.
*/
public addArgumentValues(other: ConstructorArgumentValues): void {
if (other != null) {
other.indexedArgumentValues.forEach((valueHolder, key, map) => {
this.addOrMergeIndexedArgumentValue(key, valueHolder.copy());
});
other.genericArgumentValues.filter((valueHolder, index, array) => {
return -1 === this.genericArgumentValues.indexOf(valueHolder);
}).forEach((valueHolder, index, array) => {
this.addOrMergeGenericArgumentValue(valueHolder.copy());
});
}
}
/**
* Add an argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param newValue the argument value in the form of a ValueHolder
*/
public addIndexedArgumentValue(index: number, value: ValueHolder): void;
/**
* Add an argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param value the argument value
* @param type the type of the constructor argument
*/
public addIndexedArgumentValue(index: number, value: any, type?: ClassType): void {
Assert.isTrue(index >= 0, 'Index must not be negative');
let newValue: ValueHolder;
if (!(value instanceof ValueHolder)) {
newValue = new ValueHolder(value, type);
}
Assert.notNull(newValue, 'ValueHolder must not be null');
this.addOrMergeIndexedArgumentValue(index, newValue);
}
/**
* Add an argument value for the given index in the constructor argument list,
* merging the new value (typically a collection) with the current value
* if demanded: see {@link org.springframework.beans.Mergeable}.
* @param key the index in the constructor argument list
* @param newValue the argument value in the form of a ValueHolder
*/
private addOrMergeIndexedArgumentValue(key: number, newValue: ValueHolder): void {
let currentValue: ValueHolder = this.indexedArgumentValues.get(key);
if (currentValue !== undefined && newValue.getValue() instanceof Mergeable) {
let mergeable: Mergeable = <Mergeable>newValue.getValue();
if (mergeable.isMergeEnabled()) {
newValue.setValue(mergeable.merge(currentValue.getValue()));
}
}
this.indexedArgumentValues.set(key, newValue);
}
/**
* Check whether an argument value has been registered for the given index.
* @param index the index in the constructor argument list
*/
public hasIndexedArgumentValue(index: number): boolean {
return this.indexedArgumentValues.has(index);
}
/**
* Get argument value for the given index in the constructor argument list.
* @param index the index in the constructor argument list
* @param requiredType the type to match (can be {@code null} to match
* untyped values only)
* @param requiredName the type to match (can be {@code null} to match
* unnamed values only, or empty String to match any name)
* @return the ValueHolder for the argument, or {@code null} if none set
*/
public getIndexedArgumentValue(index: number, requiredType: ClassType, requiredName?: PropertyType): ValueHolder {
Assert.isTrue(index >= 0, 'Index must not be negative');
let valueHolder: ValueHolder = this.indexedArgumentValues.get(index);
if (undefined !== valueHolder &&
(valueHolder.getType() == null ||
(requiredType != null && ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) &&
(valueHolder.getName() == null || "".equals(requiredName) ||
(requiredName != null && requiredName.equals(valueHolder.getName())))) {
return valueHolder;
}
return null;
}
/**
* Return the map of indexed argument values.
* @return unmodifiable Map with Integer index as key and ValueHolder as value
* @see ValueHolder
*/
public getIndexedArgumentValues(): Map<number, ValueHolder> {
return Collections.unmodifiableMap(this.indexedArgumentValues);
}
/**
* Add a generic argument value to be matched by type.
* <p>Note: A single generic argument value will just be used once,
* rather than matched multiple times.
* @param value the argument value
*/
public addGenericArgumentValue(value: any): void {
this.genericArgumentValues.add(new ValueHolder(value));
}
/**
* Add a generic argument value to be matched by type.
* <p>Note: A single generic argument value will just be used once,
* rather than matched multiple times.
* @param value the argument value
* @param type the type of the constructor argument
*/
public addGenericArgumentValue(value: any, type: string): void {
this.genericArgumentValues.add(new ValueHolder(value, type));
}
/**
* Add a generic argument value to be matched by type or name (if available).
* <p>Note: A single generic argument value will just be used once,
* rather than matched multiple times.
* @param newValue the argument value in the form of a ValueHolder
* <p>Note: Identical ValueHolder instances will only be registered once,
* to allow for merging and re-merging of argument value definitions. Distinct
* ValueHolder instances carrying the same content are of course allowed.
*/
public addGenericArgumentValue(newValue: ValueHolder): void {
Assert.notNull(newValue, "ValueHolder must not be null");
if (!this.genericArgumentValues.contains(newValue)) {
addOrMergeGenericArgumentValue(newValue);
}
}
/**
* Add a generic argument value, merging the new value (typically a collection)
* with the current value if demanded: see {@link org.springframework.beans.Mergeable}.
* @param newValue the argument value in the form of a ValueHolder
*/
private addOrMergeGenericArgumentValue(newValue: ValueHolder): void {
if (newValue.getName() != null) {
for (Iterator <ValueHolder> it = this.genericArgumentValues.iterator(); it.hasNext();) {
ValueHolder currentValue = it.next();
if (newValue.getName().equals(currentValue.getName())) {
if (newValue.getValue() instanceof Mergeable) {
Mergeable; mergeable = (Mergeable) newValue.getValue();
if (mergeable.isMergeEnabled()) {
newValue.setValue(mergeable.merge(currentValue.getValue()));
}
}
it.remove();
}
}
}
this.genericArgumentValues.add(newValue);
}
/**
* Look for a generic argument value that matches the given type.
* @param requiredType the type to match
* @return the ValueHolder for the argument, or {@code null} if none set
*/
public getGenericArgumentValue(requiredType: ClassType): ValueHolder {
return getGenericArgumentValue(requiredType, null, null);
}
/**
* Look for a generic argument value that matches the given type.
* @param requiredType the type to match
* @param requiredName the name to match
* @return the ValueHolder for the argument, or {@code null} if none set
*/
public getGenericArgumentValue(requiredType: ClassType, requiredName: PropertyType): ValueHolder {
return getGenericArgumentValue(requiredType, requiredName, null);
}
/**
* Look for the next generic argument value that matches the given type,
* ignoring argument values that have already been used in the current
* resolution process.
* @param requiredType the type to match (can be {@code null} to find
* an arbitrary next generic argument value)
* @param requiredName the name to match (can be {@code null} to not
* match argument values by name, or empty String to match any name)
* @param usedValueHolders a Set of ValueHolder objects that have already been used
* in the current resolution process and should therefore not be returned again
* @return the ValueHolder for the argument, or {@code null} if none found
*/
public getGenericArgumentValue(requiredType: ClassType, requiredName: string, usedValueHolders: Set<ValueHolder>): ValueHolder {
for (ValueHolder valueHolder : this.genericArgumentValues) {
if (usedValueHolders != null && usedValueHolders.contains(valueHolder)) {
continue;
}
if (valueHolder.getName() != null && !''.equals(requiredName) &&
(requiredName == null || !valueHolder.getName().equals(requiredName))) {
continue;
}
if (valueHolder.getType() != null &&
(requiredType == null || !ClassUtils.matchesTypeName(requiredType, valueHolder.getType()))) {
continue;
}
if (requiredType != null && valueHolder.getType() == null && valueHolder.getName() == null &&
!ClassUtils.isAssignableValue(requiredType, valueHolder.getValue())) {
continue;
}
return valueHolder;
}
return null;
}
/**
* Return the list of generic argument values.
* @return unmodifiable List of ValueHolders
* @see ValueHolder
*/
public getGenericArgumentValues(): ValueHolder[] {
return Collections.unmodifiableList(this.genericArgumentValues);
}
/**
* Look for an argument value that either corresponds to the given index
* in the constructor argument list or generically matches by type.
* @param index the index in the constructor argument list
* @param requiredType the parameter type to match
* @return the ValueHolder for the argument, or {@code null} if none set
*/
public getArgumentValue(index: number, requiredType: ClassType): ValueHolder {
return getArgumentValue(index, requiredType, null, null);
}
/**
* Look for an argument value that either corresponds to the given index
* in the constructor argument list or generically matches by type.
* @param index the index in the constructor argument list
* @param requiredType the parameter type to match
* @param requiredName the parameter name to match
* @return the ValueHolder for the argument, or {@code null} if none set
*/
public getArgumentValue(index: number, requiredType: ClassType, requiredName: string): ValueHolder {
return getArgumentValue(index, requiredType, requiredName, null);
}
/**
* Look for an argument value that either corresponds to the given index
* in the constructor argument list or generically matches by type.
* @param index the index in the constructor argument list
* @param requiredType the parameter type to match (can be {@code null}
* to find an untyped argument value)
* @param requiredName the parameter name to match (can be {@code null}
* to find an unnamed argument value, or empty String to match any name)
* @param usedValueHolders a Set of ValueHolder objects that have already
* been used in the current resolution process and should therefore not
* be returned again (allowing to return the next generic argument match
* in case of multiple generic argument values of the same type)
* @return the ValueHolder for the argument, or {@code null} if none set
*/
public getArgumentValue(index: number, requiredType: ClassType, requiredName: string, usedValueHolders: Set<ValueHolder>): ValueHolder {
Assert.isTrue(index >= 0, 'Index must not be negative');
ValueHolder; valueHolder = getIndexedArgumentValue(index, requiredType, requiredName);
if (valueHolder == null) {
valueHolder = getGenericArgumentValue(requiredType, requiredName, usedValueHolders);
}
return valueHolder;
}
/**
* Return the number of argument values held in this instance,
* counting both indexed and generic argument values.
*/
public getArgumentCount(): number {
return (this.indexedArgumentValues.size() + this.genericArgumentValues.size());
}
/**
* Return if this holder does not contain any argument values,
* neither indexed ones nor generic ones.
*/
public isEmpty(): boolean {
return (this.indexedArgumentValues.isEmpty() && this.genericArgumentValues.isEmpty());
}
/**
* Clear this holder, removing all argument values.
*/
public clear(): void {
this.indexedArgumentValues.clear();
this.genericArgumentValues.clear();
}
} }
@ -348,19 +42,10 @@ export class ConstructorArgumentValues {
*/ */
export class ValueHolder implements PouchMetadataElement { export class ValueHolder implements PouchMetadataElement {
private value: any; private value: any;
private type: string; private type: string;
private name: string; private name: string;
private source: any; private source: any;
private converted: boolean = false; private converted: boolean = false;
private convertedValue: any; private convertedValue: any;
/** /**
@ -470,23 +155,13 @@ export class ValueHolder implements PouchMetadataElement {
(ObjectUtils.nullSafeEquals(this.value, other.value) && ObjectUtils.nullSafeEquals(this.type, other.type))); (ObjectUtils.nullSafeEquals(this.value, other.value) && ObjectUtils.nullSafeEquals(this.type, other.type)));
} }
/**
* Determine whether the hash code of the content of this ValueHolder.
* <p>Note that ValueHolder does not implement {@code hashCode}
* directly, to allow for multiple ValueHolder instances with the
* same content to reside in the same Set.
*/
private contentHashCode(): number {
return ObjectUtils.nullSafeHashCode(this.value) * 29 + ObjectUtils.nullSafeHashCode(this.type);
}
/** /**
* Create a copy of this ValueHolder: that is, an independent * Create a copy of this ValueHolder: that is, an independent
* ValueHolder instance with the same contents. * ValueHolder instance with the same contents.
*/ */
public copy(): ValueHolder { public copy(): ValueHolder {
ValueHolder; copy = new ValueHolder(this.value, this.type, this.name); let copy: ValueHolder = new ValueHolder(this.value, this.type, this.name);
copy.setSource(this.source); copy.Source = this.Source;
return copy; return copy;
} }
} }

View File

@ -1,7 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import PouchFactory from '@loafer/pouches/factory/PouchFactory'; import PouchFactory from '@loafer/pouches/factory/PouchFactory';
export interface InjectCapablePouchFactory extends PouchFactory { export interface InjectCapablePouchFactory extends PouchFactory {

View File

@ -1,18 +1,13 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import { import {
PouchScope, PouchScope,
} from '@loafer/pouches/constants/types'; } from '@loafer/pouches/constants/types';
interface PouchDefinition { export interface PouchDefinition {
/** /**
* The name of the parent definition of this pouch definition, if any. * The name of the parent definition of this pouch definition, if any.
*/ */
ParentName: PropertyType; ParentName: PouchName;
/** /**
* The current pouch class name of this pouch definition. * The current pouch class name of this pouch definition.
* <p>Note that this does not have to be the actual class name used at runtime, in * <p>Note that this does not have to be the actual class name used at runtime, in
@ -42,7 +37,7 @@ interface PouchDefinition {
* The names of the pouchs that this pouch depends on being initialized. * The names of the pouchs that this pouch depends on being initialized.
* The pouch factory will guarantee that these pouchs get initialized first. * The pouch factory will guarantee that these pouchs get initialized first.
*/ */
DependsOn: PropertyType[]; DependsOn: PouchName[];
/** /**
* Whether this pouch is a candidate for getting autowired into some other pouch. * Whether this pouch is a candidate for getting autowired into some other pouch.
* <p>Note that this flag is designed to only affect type-based autowiring. * <p>Note that this flag is designed to only affect type-based autowiring.
@ -62,7 +57,7 @@ interface PouchDefinition {
* This the name of the pouch to call the specified factory method on. * This the name of the pouch to call the specified factory method on.
* @see #setFactoryMethodName * @see #setFactoryMethodName
*/ */
FactoryPouchName: PropertyType; FactoryPouchName: PouchName;
/** /**
* Specify a factory method, if any. This method will be invoked with * Specify a factory method, if any. This method will be invoked with
* constructor arguments, or with no arguments if none are specified. * constructor arguments, or with no arguments if none are specified.
@ -71,7 +66,7 @@ interface PouchDefinition {
* @see #setFactoryPouchName * @see #setFactoryPouchName
* @see #setPouchClassName * @see #setPouchClassName
*/ */
FactoryMethodName: PropertyType; FactoryMethodName: PropertyName;
/** /**
* Return the constructor argument values for this pouch. * Return the constructor argument values for this pouch.
* <p>The returned instance can be modified during pouch factory post-processing. * <p>The returned instance can be modified during pouch factory post-processing.

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import ConfigurablePouchFactory from '@loafer/pouches/factory/config/ConfigurablePouchFactory'; import ConfigurablePouchFactory from '@loafer/pouches/factory/config/ConfigurablePouchFactory';
import Scope from '@loafer/pouches/factory/config/Scope'; import Scope from '@loafer/pouches/factory/config/Scope';

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import PouchExpressionContext from '@loafer/pouches/factory/config/PouchExpressionContext'; import PouchExpressionContext from '@loafer/pouches/factory/config/PouchExpressionContext';
export interface PouchExpressionResolver { export interface PouchExpressionResolver {

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import ObjectFactory from '@loafer/pouches/factory/ObjectFactory'; import ObjectFactory from '@loafer/pouches/factory/ObjectFactory';
export interface Scope { export interface Scope {

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
export interface SingletonPouchRegistry { export interface SingletonPouchRegistry {
} }

View File

@ -1,8 +1,3 @@
// import {
// ClassType,
// PropertyType,
// } from '@loafer/core/constants/types';
// import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition'; // import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
// import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry'; // import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
// import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/implement/DefaultSingletonPouchRegistry'; // import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/implement/DefaultSingletonPouchRegistry';
@ -10,7 +5,7 @@
// abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implements PouchDefinitionRegistry { // abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implements PouchDefinitionRegistry {
// protected pouchDefinitionMap: Map<PropertyType, Map<ClassType, PouchDefinition>>; // protected pouchDefinitionMap: Map<Identity<T>, Map<Class<any>, PouchDefinition>>;
// public constructor() { // public constructor() {
// super(); // super();
@ -32,7 +27,7 @@
// // map.set(clazz, pouchDefinition); // // map.set(clazz, pouchDefinition);
// } // }
// public getPouchDefinition(qualifier: PropertyType, clazz?: ClassType): PouchDefinition { // public getPouchDefinition(qualifier: Identity<T>, clazz?: Class<any>): PouchDefinition {
// if (!this.pouchDefinitionMap.has(qualifier)) { // if (!this.pouchDefinitionMap.has(qualifier)) {
// return undefined; // return undefined;
// } // }
@ -47,22 +42,22 @@
// return pouchDefinition; // return pouchDefinition;
// } // }
// public getPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): PouchDefinition { // public getPouchDefinitionByClass(clazz: Class<any>, qualifier?: Identity<T>): PouchDefinition {
// // const _qualifier = validateQualifier(clazz, qualifier); // // const _qualifier = validateQualifier(clazz, qualifier);
// return this.getPouchDefinition(qualifier, clazz); // return this.getPouchDefinition(qualifier, clazz);
// } // }
// public hasPouchDefinition(qualifier: PropertyType, clazz?: ClassType): boolean { // public hasPouchDefinition(qualifier: Identity<T>, clazz?: Class<any>): boolean {
// return undefined === this.getPouchDefinition(qualifier, clazz) ? false : true; // return undefined === this.getPouchDefinition(qualifier, clazz) ? false : true;
// } // }
// public hasPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): boolean { // public hasPouchDefinitionByClass(clazz: Class<any>, qualifier?: Identity<T>): boolean {
// // const _qualifier = validateQualifier(clazz, qualifier); // // const _qualifier = validateQualifier(clazz, qualifier);
// return this.hasPouchDefinition(qualifier, clazz); // return this.hasPouchDefinition(qualifier, clazz);
// } // }
// public removePouchDefinition(qualifier: PropertyType, clazz?: ClassType): void { // public removePouchDefinition(qualifier: Identity<T>, clazz?: Class<any>): void {
// if (!this.hasPouchDefinition(qualifier, clazz)) { // if (!this.hasPouchDefinition(qualifier, clazz)) {
// console.log(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is not exist`); // console.log(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is not exist`);
@ -74,14 +69,14 @@
// } // }
// } // }
// public removePouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): void { // public removePouchDefinitionByClass(clazz: Class<any>, qualifier?: Identity<T>): void {
// // const _qualifier = validateQualifier(clazz, qualifier); // // const _qualifier = validateQualifier(clazz, qualifier);
// // this.removePouchDefinition(_qualifier, clazz); // // this.removePouchDefinition(_qualifier, clazz);
// } // }
// private _getDefinition(map: Map<ClassType, PouchDefinition>, clazz?: ClassType): PouchDefinition { // private _getDefinition(map: Map<Class<any>, PouchDefinition>, clazz?: Class<any>): PouchDefinition {
// if (undefined !== clazz) { // if (undefined !== clazz) {
// return map.get(clazz); // return map.get(clazz);
// } // }

View File

@ -1,8 +1,3 @@
// import {
// ClassType,
// PropertyType,
// } from '@loafer/core/constants/types';
// import { // import {
// PouchScope, // PouchScope,
// } from '@loafer/pouches/constants/types'; // } from '@loafer/pouches/constants/types';
@ -16,7 +11,7 @@
// public constructor() { // public constructor() {
// super(); // super();
// } // }
// public getPouch(qualifier: PropertyType, clazz: ClassType, ...args: any[]): any { // public getPouch(qualifier: Identity<T>, clazz: Class<any>, ...args: any[]): any {
// let pouchDefinition = this._getPouchDefinition(qualifier, clazz); // let pouchDefinition = this._getPouchDefinition(qualifier, clazz);
// if (undefined === pouchDefinition) { // if (undefined === pouchDefinition) {
// throw new Error(`This class[${clazz.constructor.name}:${qualifier}] is not pouch.`); // throw new Error(`This class[${clazz.constructor.name}:${qualifier}] is not pouch.`);
@ -24,7 +19,7 @@
// return this._getPouch(pouchDefinition, ...args); // return this._getPouch(pouchDefinition, ...args);
// } // }
// public getPouchByClass(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any { // public getPouchByClass(clazz: Class<any>, qualifier: Identity<T>, ...args: any[]): any {
// // let _qualifier = validateQualifier(clazz, qualifier); // // let _qualifier = validateQualifier(clazz, qualifier);
// // let pouchDefinition = this._getPouchDefinition(_qualifier, clazz); // // let pouchDefinition = this._getPouchDefinition(_qualifier, clazz);
@ -35,7 +30,7 @@
// // return this._getPouch(pouchDefinition, ...args); // // return this._getPouch(pouchDefinition, ...args);
// } // }
// private _getPouchDefinition(qualifier: PropertyType, clazz: ClassType): PouchDefinition { // private _getPouchDefinition(qualifier: Identity<T>, clazz: Class<any>): PouchDefinition {
// let pouchDefinition = this.getPouchDefinition(qualifier, clazz); // let pouchDefinition = this.getPouchDefinition(qualifier, clazz);
// if (undefined === pouchDefinition) { // if (undefined === pouchDefinition) {
@ -62,14 +57,14 @@
// this._injectDependency(instance, pouchDefinition.Clazz); // this._injectDependency(instance, pouchDefinition.Clazz);
// } // }
// private _injectDependency(instance: any, clazz: ClassType): void { // private _injectDependency(instance: any, clazz: Class<any>): void {
// if (clazz.constructor === Object) { // if (clazz.constructor === Object) {
// return; // return;
// } // }
// // let injectDefinition: InjectDefinition = this._getInjectDefinition(clazz); // // let injectDefinition: InjectDefinition = this._getInjectDefinition(clazz);
// // if (undefined !== injectDefinition) { // // if (undefined !== injectDefinition) {
// // let injectors: Map<PropertyType, InjectItem> = injectDefinition.injectors; // // let injectors: Map<Identity<T>, InjectItem> = injectDefinition.injectors;
// // let propertyDescriptor: PropertyDescriptor; // // let propertyDescriptor: PropertyDescriptor;
// // injectors.forEach((injectItem, key, map) => { // // injectors.forEach((injectItem, key, map) => {
// // propertyDescriptor = Object.getOwnPropertyDescriptor(clazz, key); // // propertyDescriptor = Object.getOwnPropertyDescriptor(clazz, key);
@ -89,7 +84,7 @@
// // this._injectDependency(instance, Object.getPrototypeOf(clazz)); // // this._injectDependency(instance, Object.getPrototypeOf(clazz));
// } // }
// // private _injectDependencyProperty(instance: any, clazz: ClassType, propertyKey: PropertyType, // // private _injectDependencyProperty(instance: any, clazz: Class<any>, propertyKey: Identity<T>,
// // propertyDescriptor: PropertyDescriptor, injectConfig: InjectConfig): void { // // propertyDescriptor: PropertyDescriptor, injectConfig: InjectConfig): void {
// // let pouch = this.getPouchByClass(injectConfig.clazz, injectConfig.qualifier); // // let pouch = this.getPouchByClass(injectConfig.clazz, injectConfig.qualifier);
// // if (injectConfig.required && undefined === instance) { // // if (injectConfig.required && undefined === instance) {
@ -103,11 +98,11 @@
// // console.log(''); // // console.log('');
// // } // // }
// // private _getInjectableDefinition(clazz: ClassType): InjectableDefinition { // // private _getInjectableDefinition(clazz: Class<any>): InjectableDefinition {
// // return Reflect.getMetadata(POUCH_INJECTABLE_DEFINITION, clazz); // // return Reflect.getMetadata(POUCH_INJECTABLE_DEFINITION, clazz);
// // } // // }
// // private _getInjectDefinition(clazz: ClassType): InjectDefinition { // // private _getInjectDefinition(clazz: Class<any>): InjectDefinition {
// // return Reflect.getMetadata(POUCH_INJECT_DEFINITION, clazz); // // return Reflect.getMetadata(POUCH_INJECT_DEFINITION, clazz);
// // } // // }
// } // }

View File

@ -1,19 +1,14 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import SingletonPouchRegistry from '@loafer/pouches/factory/config/SingletonPouchRegistry'; import SingletonPouchRegistry from '@loafer/pouches/factory/config/SingletonPouchRegistry';
class DefaultSingletonPouchRegistry implements SingletonPouchRegistry { class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
protected singletonInstanceMap: Map<PropertyType, Map<ClassType, any>>; protected singletonInstanceMap: Map<PouchName, Map<Class<any>, any>>;
protected constructor() { protected constructor() {
this.singletonInstanceMap = new Map(); this.singletonInstanceMap = new Map();
} }
public registerSingleton(pouch: any, qualifier?: PropertyType): void { public registerSingleton(pouch: any, qualifier?: QualifierName): void {
let clazz: ClassType = Object.getPrototypeOf(pouch); let clazz: Class<any> = Object.getPrototypeOf(pouch);
// const _qualifier = validateQualifier(clazz, qualifier); // const _qualifier = validateQualifier(clazz, qualifier);
// if (this._hasSingleton(_qualifier, clazz)) { // if (this._hasSingleton(_qualifier, clazz)) {
@ -27,23 +22,23 @@ class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
// map.set(clazz, pouch); // map.set(clazz, pouch);
} }
public getSingleton(qualifier: PropertyType, clazz?: ClassType): any { public getSingleton(qualifier: QualifierName, clazz?: Class<any>): any {
return this._getSingleton(qualifier, clazz); return this._getSingleton(qualifier, clazz);
} }
public getSingletonByClass(clazz: ClassType, qualifier?: PropertyType): any { public getSingletonByClass(clazz: Class<any>, qualifier?: QualifierName): any {
// const _qualifier = validateQualifier(clazz, qualifier); // const _qualifier = validateQualifier(clazz, qualifier);
return this._getSingleton(qualifier, clazz); return this._getSingleton(qualifier, clazz);
} }
public hasSingleton(qualifier: PropertyType, clazz?: ClassType): boolean { public hasSingleton(qualifier: QualifierName, clazz?: Class<any>): boolean {
return this._hasSingleton(qualifier, clazz); return this._hasSingleton(qualifier, clazz);
} }
public hasSingletonByClass(clazz: ClassType, qualifier?: PropertyType): boolean { public hasSingletonByClass(clazz: Class<any>, qualifier?: QualifierName): boolean {
// const _qualifier = validateQualifier(clazz, qualifier); // const _qualifier = validateQualifier(clazz, qualifier);
return this._hasSingleton(qualifier, clazz); return this._hasSingleton(qualifier, clazz);
} }
private _getSingleton<T>(qualifier: PropertyType, clazz?: ClassType): T { private _getSingleton<T>(qualifier: QualifierName, clazz?: Class<any>): T {
if (!this.singletonInstanceMap.has(qualifier)) { if (!this.singletonInstanceMap.has(qualifier)) {
return undefined; return undefined;
} }
@ -57,11 +52,11 @@ class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
return instance; return instance;
} }
private _hasSingleton(qualifier: PropertyType, clazz?: ClassType): boolean { private _hasSingleton(qualifier: QualifierName, clazz?: Class<any>): boolean {
return undefined === this._getSingleton(qualifier, clazz) ? false : true; return undefined === this._getSingleton(qualifier, clazz) ? false : true;
} }
private _getInstance(map: Map<ClassType, any>, clazz?: ClassType): any { private _getInstance(map: Map<Class<any>, any>, clazz?: Class<any>): any {
if (undefined !== clazz) { if (undefined !== clazz) {
return map.get(clazz); return map.get(clazz);
} }

View File

@ -0,0 +1,12 @@
import {
PouchMetadataAttributeAccessor,
} from '@loafer/pouches';
import {
PouchDefinition,
} from '@loafer/pouches/factory/config';
export abstract class AbstractPouchDefinition extends PouchMetadataAttributeAccessor implements PouchDefinition {
}
export default AbstractPouchDefinition;

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import SimpleAliasRegistry from '@loafer/core/SimpleAliasRegistry'; import SimpleAliasRegistry from '@loafer/core/SimpleAliasRegistry';
import ObjectFactory from '@loafer/pouches/factory/ObjectFactory'; import ObjectFactory from '@loafer/pouches/factory/ObjectFactory';
import DisposablePouch from '@loafer/pouches/factory/DisposablePouch'; import DisposablePouch from '@loafer/pouches/factory/DisposablePouch';

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import AliasRegistry from '@loafer/core/AliasRegistry'; import AliasRegistry from '@loafer/core/AliasRegistry';
import FactoryPouch from '@loafer/pouches/factory/FactoryPouch'; import FactoryPouch from '@loafer/pouches/factory/FactoryPouch';
import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/support/DefaultSingletonPouchRegistry'; import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/support/DefaultSingletonPouchRegistry';

View File

@ -0,0 +1,8 @@
import {
AbstractPouchDefinition,
} from '@loafer/pouches/factory/support';
export class GenericPouchDefinition extends AbstractPouchDefinition {
}
export default GenericPouchDefinition;

View File

@ -1,6 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import AliasRegistry from '@loafer/core/AliasRegistry'; import AliasRegistry from '@loafer/core/AliasRegistry';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition'; import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
import { import {
@ -22,14 +19,14 @@ export interface PouchDefinitionRegistry extends AliasRegistry {
* @see RootPouchDefinition * @see RootPouchDefinition
* @see ChildPouchDefinition * @see ChildPouchDefinition
*/ */
registerPouchDefinition(pouchName: PropertyType, pouchDefinition: PouchDefinition): void; registerPouchDefinition(pouchName: PouchName, pouchDefinition: PouchDefinition): void;
/** /**
* Remove the PouchDefinition for the given name. * Remove the PouchDefinition for the given name.
* @param pouchName the name of the pouch instance to register * @param pouchName the name of the pouch instance to register
* @throws NoSuchPouchDefinitionException if there is no such pouch definition * @throws NoSuchPouchDefinitionException if there is no such pouch definition
*/ */
removePouchDefinition(pouchName: PropertyType): void; removePouchDefinition(pouchName: PouchName): void;
/** /**
* Return the PouchDefinition for the given pouch name. * Return the PouchDefinition for the given pouch name.
@ -37,21 +34,21 @@ export interface PouchDefinitionRegistry extends AliasRegistry {
* @return the PouchDefinition for the given name (never {@code null}) * @return the PouchDefinition for the given name (never {@code null})
* @throws NoSuchPouchDefinitionException if there is no such pouch definition * @throws NoSuchPouchDefinitionException if there is no such pouch definition
*/ */
getPouchDefinition(pouchName: PropertyType): PouchDefinition; getPouchDefinition(pouchName: PouchName): PouchDefinition;
/** /**
* Check if this registry contains a pouch definition with the given name. * Check if this registry contains a pouch definition with the given name.
* @param pouchName the name of the pouch to look for * @param pouchName the name of the pouch to look for
* @return if this registry contains a pouch definition with the given name * @return if this registry contains a pouch definition with the given name
*/ */
containsPouchDefinition(pouchName: PropertyType): boolean; containsPouchDefinition(pouchName: PouchName): boolean;
/** /**
* Return the names of all pouchs defined in this registry. * Return the names of all pouchs defined in this registry.
* @return the names of all pouchs defined in this registry, * @return the names of all pouchs defined in this registry,
* or an empty array if none defined * or an empty array if none defined
*/ */
getPouchDefinitionNames(): PropertyType[]; getPouchDefinitionNames(): PouchName[];
/** /**
* Return the number of pouchs defined in the registry. * Return the number of pouchs defined in the registry.
@ -65,7 +62,7 @@ export interface PouchDefinitionRegistry extends AliasRegistry {
* @param pouchName the name to check * @param pouchName the name to check
* @return whether the given pouch name is already in use * @return whether the given pouch name is already in use
*/ */
isPouchNameInUse(pouchName: PropertyType): boolean; isPouchNameInUse(pouchName: PouchName): boolean;
} }
export default PouchDefinitionRegistry; export default PouchDefinitionRegistry;

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import AliasRegistry from '@loafer/core/AliasRegistry'; import AliasRegistry from '@loafer/core/AliasRegistry';
import { import {
@ -25,7 +20,7 @@ export interface PouchNameGenerator {
* is supposed to be registered with * is supposed to be registered with
* @return the generated pouch name * @return the generated pouch name
*/ */
generatePouchName(definition: PouchDefinition, registry: PouchDefinitionRegistry): PropertyType; generatePouchName(definition: PouchDefinition, registry: PouchDefinitionRegistry): PouchName;
} }
export default PouchNameGenerator; export default PouchNameGenerator;

View File

@ -1,6 +1,9 @@
export * from './AbstractInjectCapablePouchFactory'; export * from './AbstractInjectCapablePouchFactory';
export * from './AbstractPouchFactory'; export * from './AbstractPouchFactory';
export * from './AbstractPouchDefinition';
export * from './DefaultListablePouchFactory'; export * from './DefaultListablePouchFactory';
export * from './DefaultSingletonPouchRegistry'; export * from './DefaultSingletonPouchRegistry';
export * from './FactoryPouchRegistrySupport'; export * from './FactoryPouchRegistrySupport';
export * from './PouchDefinitionRegistry'; export * from './PouchDefinitionRegistry';
export * from './GenericPouchDefinition';

View File

@ -1,3 +1,4 @@
export * from './PouchesException'; export * from './PouchesException';
export * from './Mergeable';
export * from './PouchMetadataElement'; export * from './PouchMetadataElement';
export * from './PouchMetadataAttributeAccessor';

View File

@ -56,6 +56,7 @@ import appConfig, { Config, ReduxState } from './config';
import * as AppView from './views/App'; import * as AppView from './views/App';
declare global { declare global {
interface Window { interface Window {
devToolsExtension: () => any; devToolsExtension: () => any;