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 ApplicationStater from '@loafer/application/ApplicationStater';
class Application {
// private appContext: AppContext;
private appClass: ClassType;
private appClass: Class<any>;
// private appInstance: ApplicationStater;
public constructor(clazz: ClassType) {
public constructor(clazz: Class<any>) {
this.appClass = clazz;
}
@ -23,7 +19,7 @@ class Application {
context.getPouch('entitlement');
}
public static run(clazz: ClassType): void {
public static run(clazz: Class<any>): void {
new Application(clazz).run();
}
}

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import {
Decorator,
} from '@loafer/core/decorator';
@ -11,7 +7,7 @@ import {
} from '@loafer/context/decorator/Configuration';
export class ApplicationConfigurationAnnotation extends ConfigurationAnnotation {
public constructor(qualifier?: PropertyType) {
public constructor(qualifier?: QualifierName) {
super(qualifier);
}
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 PouchFactory from '@loafer/pouches/factory/PouchFactory';
@ -11,7 +7,7 @@
// import InjectCapablePouchFactory from '@loafer/pouches/factory/config/InjectCapablePouchFactory';
// export interface ApplicationContext extends EnvironmentCapable, ListablePouchFactory, HierarchicalPouchFactory {
// getId?(): PropertyType;
// getId?(): Identity<T>;
// getApplicationName(): string;
// getDisplayName(): string;
// getParent?(): ApplicationContext;

View File

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

View File

@ -1,8 +1,3 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import {
Assert,
} from '@loafer/core/util';
@ -15,6 +10,11 @@ import {
PouchDefinitionRegistry,
} from '@loafer/pouches/factory/support';
import {
AnnotatedGenericPouchDefinition,
} from '@loafer/pouches/factory/annotation';
import GenericApplicationContext from '@loafer/context/support/GenericApplicationContext';
@ -36,65 +36,75 @@ export class AnnotatedPouchDefinitionReader {
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.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public register(...annotatedClasses: Class<any>[]): void {
annotatedClasses.forEach(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);
}
public setEnvironment(environment: Environment): void {
this.conditionEvaluator = new ConditionEvaluator(this.registry, environment, 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 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 => {
this.registerPouch(annotatedClass);
});
}
public registerPouch<TAnnotation extends Annotation>(annotatedClass: ClassType, name: PropertyType, ...qualifiers: TAnnotation[]): void {
let abd: AnnotatedGenericPouchDefinition = new AnnotatedGenericPouchDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
let scopeMetadata: ScopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
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);
if (qualifiers !== undefined) {
qualifiers.forEach((qualifier, index, array) => {
if (qualifiers != null) {
qualifiers.forEach((qualifier, index) => {
if (Primary.class === qualifier) {
abd.setPrimary(true);
} else if (Lazy.class === qualifier) {
}
else if (Lazy.class === qualifier) {
abd.setLazyInit(true);
} else {
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
});
});
}
definitionCustomizers.forEach((customizer) => {
customizer.customize(abd);
});
let definitionHolder: PouchDefinitionHolder = new PouchDefinitionHolder(abd, pouchName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, 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;

View File

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

View File

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

View File

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

View File

@ -1,12 +1,8 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
export interface AliasRegistry {
registerAlias(name: PropertyType, alias: PropertyType): void;
removeAlias(alias: PropertyType): void;
isAlias(name: PropertyType): boolean;
getAliases(name: PropertyType): PropertyType[];
registerAlias(name: PouchName, alias: PouchName): void;
removeAlias(alias: PouchName): void;
isAlias(name: PouchName): boolean;
getAliases(name: PouchName): PouchName[];
}
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 Parameter from '@loafer/core/reflect/Parameter';
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';
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 {
onClassDecorator?: <TFunction extends Function>(target: TFunction) => TFunction | void;
onPropertyDecorator?: (target: Object, propertyKey: PropertyType) => void;
onMethodDecorator?: <T>(target: Object, propertyKey: PropertyType,
onPropertyDecorator?: (target: Object, propertyKey: PropertyName) => void;
onMethodDecorator?: <T>(target: Object, propertyKey: PropertyName,
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 {

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 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 DecoratorType from './DecoratorType';
export class Decorator {
public static create = (AnnotationType: Construtorable<Annotation>) => {
public static create = (AnnotationType: Class<Annotation>) => {
return (...handlerArgs: any[]) => {
let annotation: Annotation = new AnnotationType(...handlerArgs);
@ -22,7 +18,7 @@ export class Decorator {
reflection = new Reflection(type);
Reflect.defineMetadata(ReflectConstants.REFLECT_META, reflection, type);
}
let clazz: Class = reflection.getClass();
let clazz: Clazz = reflection.getClass();
switch(decoratorType) {
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);
if (undefined === reflection) {
return undefined;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,15 +1,11 @@
import {
ClassType,
} from '@loafer/core/constants/types';
export abstract class AnnotatedElement {
private _annotationMap: Map<ClassType, any>;
private _annotationMap: Map<Class<any>, any>;
protected constructor() {
this._annotationMap = new Map();
}
public getDeclaredAnnotation(type: ClassType): any {
public getDeclaredAnnotation(type: Class<any>): any {
return this._annotationMap.get(type);
}
public getDeclaredAnnotations(): IterableIterator<any> {
@ -17,15 +13,15 @@ export abstract class AnnotatedElement {
}
public addAnnotation(annotation: any): void {
const type: ClassType = Object.getPrototypeOf(annotation);
const type: Class<any> = Object.getPrototypeOf(annotation);
this._annotationMap.set(type, annotation);
}
public hasAnnotation(type: ClassType): boolean {
public hasAnnotation(type: Class<any>): boolean {
return this._annotationMap.has(type);
}
// public abstract getAnnotation(type: ClassType): any;
// public abstract getAnnotation(type: Class<any>): 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 Constructor from './Constructor';
import Property from './Property';
import Method from './Method';
export class Class extends AnnotatedElement {
private _type: ClassType;
private _name: PropertyType;
export class Clazz extends AnnotatedElement {
private _type: Class<any>;
private _name: PropertyName;
private _constructor: Constructor;
private _properties: Map<PropertyType, Property>;
private _methodes: Map<PropertyType, Method>;
private _properties: Map<PropertyName, Property>;
private _methodes: Map<PropertyName, Method>;
public constructor(type: ClassType, parameterTypes: ClassType[]) {
public constructor(type: Class<any>, parameterTypes: Class<any>[]) {
super();
this._type = type;
this._name = this._type.constructor.name;
@ -25,11 +20,11 @@ export class Class extends AnnotatedElement {
this._methodes = new Map();
}
public get Type(): ClassType {
public get Type(): Class<any> {
return this._type;
}
public get Name(): PropertyType {
public get Name(): PropertyName {
return this._name;
}
@ -37,39 +32,39 @@ export class Class extends AnnotatedElement {
return this._constructor;
}
public addProperty(propertyKey: PropertyType, type: ClassType): Property {
public addProperty(propertyKey: PropertyName, type: Class<any>): Property {
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);
this._properties.set(propertyKey, proerty);
return proerty;
}
public getProperty(propertyKey: PropertyType): Property {
public getProperty(propertyKey: PropertyName): Property {
return this._properties.get(propertyKey);
}
public hasProperty(propertyKey: PropertyType): boolean {
public hasProperty(propertyKey: PropertyName): boolean {
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)) {
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);
this._methodes.set(propertyKey, method);
return method;
}
public getMethod(propertyKey: PropertyType): Method {
public getMethod(propertyKey: PropertyName): Method {
return this._methodes.get(propertyKey);
}
public hasMethod(propertyKey: PropertyType): boolean {
public hasMethod(propertyKey: PropertyName): boolean {
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';
export class Constructor extends Executable {
public constructor(parameterTypes: ClassType[]) {
public constructor(parameterTypes: Class<any>[]) {
super(parameterTypes);
}
}

View File

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

View File

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

View File

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

View File

@ -1,27 +1,22 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import AnnotatedElement from './AnnotatedElement';
import Constructor from './Constructor';
export class Property extends AnnotatedElement {
private _type: ClassType;
private _name: PropertyType;
private _type: Class<any>;
private _name: PropertyName;
public constructor(type: ClassType, name: PropertyType) {
public constructor(type: Class<any>, name: PropertyName) {
super();
this._type = type;
this._name = name;
}
public get Name(): PropertyType {
public get Name(): PropertyName {
return this._name;
}
public get Type(): ClassType {
public get Type(): Class<any> {
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 AnnotatedElement from './AnnotatedElement';
import Class from './Class';
import Clazz from './Clazz';
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);
this._clazz = new Class(type, this.convertParamTypes(parameterTypes));
this._clazz = new Clazz(type, this.convertParamTypes(parameterTypes));
}
/**
* getClass
*/
public getClass(): Class {
public getClass(): Clazz {
return this._clazz;
}
@ -34,7 +29,7 @@ export class Reflection {
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 property = this._clazz.getProperty(propertyKey);
@ -49,7 +44,7 @@ export class Reflection {
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 returnType: any = Reflect.getMetadata(ReflectConstants.DESIGN_RETURNTYPE, this._clazz.Type, propertyKey);
@ -65,7 +60,7 @@ export class Reflection {
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 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} {
const annotationType: ClassType = Object.getPrototypeOf(annotation);
const annotationType: Class<any> = Object.getPrototypeOf(annotation);
const name: string = annotationType.constructor.name;
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};
}
private convertParamTypes(parameterTypes: any[]): ClassType[] {
let returnTypes: ClassType[] = [];
private convertParamTypes(parameterTypes: any[]): Class<any>[] {
let returnTypes: Class<any>[] = [];
parameterTypes.forEach((currentValue, index, array) => {
returnTypes.push(currentValue.prototype);
});

View File

@ -1,5 +1,5 @@
export * from './AnnotatedElement';
export * from './Class';
export * from './Clazz';
export * from './Constructor';
export * from './Executable';
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 {
IllegalStateException,
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');
if (!(obj instanceof type.constructor)) {
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 result = '';
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 './ObjectUtils';
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 {
/**
* Return the configuration source {@code Object} for this metadata element
* (may be {@code null}).
*/
getSource(): any;
}
export default PouchMetadataElement;

View File

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

View File

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

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import {
Decorator,
} from '@loafer/core/decorator';
@ -9,7 +5,7 @@ import {
import Annotation from '@loafer/core/annotation/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 => {
console.log('PostConstruct');
}

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import {
Decorator,
} from '@loafer/core/decorator';
@ -9,7 +5,7 @@ import {
import Annotation from '@loafer/core/annotation/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 => {
console.log('PreDestroy');
}

View File

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

View File

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

View File

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

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
import PouchFactory from '@loafer/pouches/factory/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 {

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';
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 HierarchicalPouchFactory from '@loafer/pouches/factory/HierarchicalPouchFactory';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';

View File

@ -1,13 +1,11 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import {
Assert,
ObjectUtils,
TypeUtils,
} from '@loafer/core/util';
import {
Mergeable,
PouchMetadataElement,
} from '@loafer/pouches';
@ -22,9 +20,6 @@ import {
SingletonPouchRegistry,
} from '@loafer/pouches/factory/config';
export class ConstructorArgumentValues {
private readonly indexedArgumentValues: Map<number, ValueHolder> = new Map();
private readonly genericArgumentValues: ValueHolder[] = [];
@ -34,311 +29,10 @@ export class ConstructorArgumentValues {
* @param original the ConstructorArgumentValues to copy
*/
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 {
private value: any;
private type: string;
private name: string;
private source: any;
private converted: boolean = false;
private convertedValue: any;
/**
@ -470,23 +155,13 @@ export class ValueHolder implements PouchMetadataElement {
(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
* ValueHolder instance with the same contents.
*/
public copy(): ValueHolder {
ValueHolder; copy = new ValueHolder(this.value, this.type, this.name);
copy.setSource(this.source);
let copy: ValueHolder = new ValueHolder(this.value, this.type, this.name);
copy.Source = this.Source;
return copy;
}
}

View File

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

View File

@ -1,18 +1,13 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import {
PouchScope,
} from '@loafer/pouches/constants/types';
interface PouchDefinition {
export interface PouchDefinition {
/**
* 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.
* <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 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.
* <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.
* @see #setFactoryMethodName
*/
FactoryPouchName: PropertyType;
FactoryPouchName: PouchName;
/**
* Specify a factory method, if any. This method will be invoked with
* constructor arguments, or with no arguments if none are specified.
@ -71,7 +66,7 @@ interface PouchDefinition {
* @see #setFactoryPouchName
* @see #setPouchClassName
*/
FactoryMethodName: PropertyType;
FactoryMethodName: PropertyName;
/**
* Return the constructor argument values for this pouch.
* <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 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';
export interface PouchExpressionResolver {

View File

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

View File

@ -1,7 +1,3 @@
import {
PropertyType,
} from '@loafer/core/constants/types';
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 PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
// import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/implement/DefaultSingletonPouchRegistry';
@ -10,7 +5,7 @@
// 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() {
// super();
@ -32,7 +27,7 @@
// // 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)) {
// return undefined;
// }
@ -47,22 +42,22 @@
// return pouchDefinition;
// }
// public getPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): PouchDefinition {
// public getPouchDefinitionByClass(clazz: Class<any>, qualifier?: Identity<T>): PouchDefinition {
// // const _qualifier = validateQualifier(clazz, qualifier);
// 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;
// }
// public hasPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): boolean {
// public hasPouchDefinitionByClass(clazz: Class<any>, qualifier?: Identity<T>): boolean {
// // const _qualifier = validateQualifier(clazz, qualifier);
// 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)) {
// 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);
// // 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) {
// return map.get(clazz);
// }

View File

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

View File

@ -1,19 +1,14 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import SingletonPouchRegistry from '@loafer/pouches/factory/config/SingletonPouchRegistry';
class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
protected singletonInstanceMap: Map<PropertyType, Map<ClassType, any>>;
protected singletonInstanceMap: Map<PouchName, Map<Class<any>, any>>;
protected constructor() {
this.singletonInstanceMap = new Map();
}
public registerSingleton(pouch: any, qualifier?: PropertyType): void {
let clazz: ClassType = Object.getPrototypeOf(pouch);
public registerSingleton(pouch: any, qualifier?: QualifierName): void {
let clazz: Class<any> = Object.getPrototypeOf(pouch);
// const _qualifier = validateQualifier(clazz, qualifier);
// if (this._hasSingleton(_qualifier, clazz)) {
@ -27,23 +22,23 @@ class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
// map.set(clazz, pouch);
}
public getSingleton(qualifier: PropertyType, clazz?: ClassType): any {
public getSingleton(qualifier: QualifierName, clazz?: Class<any>): any {
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);
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);
}
public hasSingletonByClass(clazz: ClassType, qualifier?: PropertyType): boolean {
public hasSingletonByClass(clazz: Class<any>, qualifier?: QualifierName): boolean {
// const _qualifier = validateQualifier(clazz, qualifier);
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)) {
return undefined;
}
@ -57,11 +52,11 @@ class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
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;
}
private _getInstance(map: Map<ClassType, any>, clazz?: ClassType): any {
private _getInstance(map: Map<Class<any>, any>, clazz?: Class<any>): any {
if (undefined !== 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 ObjectFactory from '@loafer/pouches/factory/ObjectFactory';
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 FactoryPouch from '@loafer/pouches/factory/FactoryPouch';
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 PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
import {
@ -22,14 +19,14 @@ export interface PouchDefinitionRegistry extends AliasRegistry {
* @see RootPouchDefinition
* @see ChildPouchDefinition
*/
registerPouchDefinition(pouchName: PropertyType, pouchDefinition: PouchDefinition): void;
registerPouchDefinition(pouchName: PouchName, pouchDefinition: PouchDefinition): void;
/**
* Remove the PouchDefinition for the given name.
* @param pouchName the name of the pouch instance to register
* @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.
@ -37,21 +34,21 @@ export interface PouchDefinitionRegistry extends AliasRegistry {
* @return the PouchDefinition for the given name (never {@code null})
* @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.
* @param pouchName the name of the pouch to look for
* @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,
* or an empty array if none defined
*/
getPouchDefinitionNames(): PropertyType[];
getPouchDefinitionNames(): PouchName[];
/**
* Return the number of pouchs defined in the registry.
@ -65,7 +62,7 @@ export interface PouchDefinitionRegistry extends AliasRegistry {
* @param pouchName the name to check
* @return whether the given pouch name is already in use
*/
isPouchNameInUse(pouchName: PropertyType): boolean;
isPouchNameInUse(pouchName: PouchName): boolean;
}
export default PouchDefinitionRegistry;

View File

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

View File

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

View File

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

View File

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