This commit is contained in:
crusader 2017-12-27 01:22:37 +09:00
parent 00583067cd
commit d3d477d8d1
28 changed files with 298 additions and 50 deletions

View File

@ -0,0 +1,52 @@
import {
Class,
} from '@overflow/commons/core/reflect';
import { ClassType } from '@overflow/commons/core/type';
import { ApplicationContext } from './context';
import {
InjectableClass,
InjectableFactory,
InjectableValue,
WebApplicationAnnotation,
} from './decorators';
export class Application {
private primaryClass: ClassType;
private applicationContext: ApplicationContext;
public static run(primaryClass: ClassType): void {
let app: Application = new Application(primaryClass);
}
public constructor(primaryClass: ClassType) {
this.primaryClass = primaryClass;
this.createContext();
}
private createContext(): void {
let clazz: Class = Class.forClass(this.primaryClass);
let wa: WebApplicationAnnotation = clazz.getOwnAnnotation(WebApplicationAnnotation);
if (undefined === wa) {
console.warn(`Class is not WebApplication type. add @WebApplication annotation to class[${this.primaryClass.name}]`);
return;
}
let context: ApplicationContext = new ApplicationContext();
// context.registerInjectables(wa.attributes.injectables);
wa.attributes.injectables.forEach(injectable => {
if (undefined !== (<InjectableClass>injectable).injectableType) {
context.registerInjectable()
} else if (undefined !== (<InjectableFactory>injectable).injectableFactory) {
console.log(`InjectableFactory`);
} else if (undefined !== (<InjectableValue>injectable).injectableValue) {
console.log(`InjectableValue`);
} else if (typeof injectable === 'function') {
console.log(`Class`);
}
});
}
}

View File

@ -0,0 +1,3 @@
export class ApplicationContext {
}

View File

@ -0,0 +1 @@
export * from './application_context';

View File

@ -0,0 +1,42 @@
import {
Annotation,
Decorator,
} from '@overflow/commons/core/reflect';
import {
ClassType,
PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type';
export interface ConfigurationAnnotationAttributes {
name?: string[];
}
export class ConfigurationAnnotation implements Annotation {
public readonly attributes: ConfigurationAnnotationAttributes;
public constructor(name: string | ConfigurationAnnotationAttributes) {
if (undefined === name) {
this.attributes = {
};
return;
}
if (TypeUtil.isString(name)) {
this.attributes = {
name: [<string>name],
};
} else {
this.attributes = <ConfigurationAnnotationAttributes>name;
}
}
public classDecorator<TFunction extends Function>(target: TFunction): TFunction | void {
// no op
}
}
export const Configuration = Decorator.create(ConfigurationAnnotation);

View File

@ -1 +1,2 @@
export * from './configuration';
export * from './web_application'; export * from './web_application';

View File

@ -5,14 +5,28 @@ import {
import { import {
ClassType, ClassType,
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
export interface InjectableClass {
injectType: ClassType;
injectableType: ClassType;
}
export interface InjectableFactory {
injectType: ClassType;
injectableFactory: (...params: any[]) => any;
}
export interface InjectableValue {
injectName: PropertyKeyType;
injectableValue: any;
}
export type InjectablesType = (ClassType | InjectableClass | InjectableFactory | InjectableValue)[];
export interface WebApplicationAnnotationAttributes { export interface WebApplicationAnnotationAttributes {
injectables?: ClassType[]; injectables?: InjectablesType;
configurations?: ClassType[]; configurations?: ClassType[];
} }
@ -24,7 +38,7 @@ export class WebApplicationAnnotation implements Annotation {
} }
public classDecorator<TFunction extends Function>(target: TFunction): TFunction | void { public classDecorator<TFunction extends Function>(target: TFunction): TFunction | void {
console.log('WebApplication'); // no op
} }
} }

View File

@ -0,0 +1 @@
export * from './application';

View File

@ -4,35 +4,36 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
export interface InjectAnnotationAttributes { export interface InjectAnnotationAttributes {
value: string[]; name?: string[];
} }
export class InjectAnnotation implements Annotation { export class InjectAnnotation implements Annotation {
public readonly attributes: InjectAnnotationAttributes; public readonly attributes: InjectAnnotationAttributes;
public constructor(value: string | string[] | InjectAnnotationAttributes) { public constructor(name: string | string[] | InjectAnnotationAttributes) {
if (undefined === value) { if (undefined === name) {
throw new Error(`value attribute must be specified.`); this.attributes = {
};
return;
} }
if (TypeUtil.isString(value)) { if (TypeUtil.isString(name)) {
this.attributes = { this.attributes = {
value: [<string>value], name: [<string>name],
}; };
} else if (TypeUtil.isArray(value)) { } else if (TypeUtil.isArray(name)) {
this.attributes = { this.attributes = {
value: <string[]>value, name: <string[]>name,
}; };
} else { } else {
this.attributes = <InjectAnnotationAttributes>value; this.attributes = <InjectAnnotationAttributes>name;
} }
} }

View File

@ -4,12 +4,10 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
export interface InjectableAnnotationAttributes { export interface InjectableAnnotationAttributes {
name?: string[]; name?: string[];
} }
@ -20,7 +18,9 @@ export class InjectableAnnotation implements Annotation {
public constructor(name: string | string[] | InjectableAnnotationAttributes) { public constructor(name: string | string[] | InjectableAnnotationAttributes) {
if (undefined === name) { if (undefined === name) {
throw new Error(`value attribute must be specified.`); this.attributes = {
};
return;
} }
if (TypeUtil.isString(name)) { if (TypeUtil.isString(name)) {

View File

@ -4,35 +4,29 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
export interface ResourceAnnotationAttributes { export interface ResourceAnnotationAttributes {
value: string[]; name: string[];
} }
export class ResourceAnnotation implements Annotation { export class ResourceAnnotation implements Annotation {
public readonly attributes: ResourceAnnotationAttributes; public readonly attributes: ResourceAnnotationAttributes;
public constructor(value: string | string[] | ResourceAnnotationAttributes) { public constructor(name: string | ResourceAnnotationAttributes) {
if (undefined === value) { if (undefined === name) {
throw new Error(`value attribute must be specified.`); throw new Error(`name attribute must be specified.`);
} }
if (TypeUtil.isString(value)) { if (TypeUtil.isString(name)) {
this.attributes = { this.attributes = {
value: [<string>value], name: [<string>name],
};
} else if (TypeUtil.isArray(value)) {
this.attributes = {
value: <string[]>value,
}; };
} else { } else {
this.attributes = <ResourceAnnotationAttributes>value; this.attributes = <ResourceAnnotationAttributes>name;
} }
} }

View File

@ -0,0 +1,14 @@
import {
ClassType,
} from '@overflow/commons/core/type';
export class InstanceDefinition {
private _instanceClass: ClassType;
public get InstanceClass(): ClassType {
return this._instanceClass;
}
public set InstanceClass(instanceClass: ClassType) {
this._instanceClass = instanceClass;
}
}

View File

@ -0,0 +1,31 @@
import { PropertyKeyType } from '@overflow/commons/core/type';
import { PropertyValue } from './property_value';
export class MutablePropertyValues {
private propertyValueList: PropertyValue[];
private processedProperties: Set<PropertyKeyType>;
public constructor(propertyValueList?: PropertyValue[]) {
if (undefined === propertyValueList) {
this.propertyValueList = [];
} else {
this.propertyValueList = propertyValueList;
}
}
public addPropertyValue(pv :PropertyValue): MutablePropertyValues {
for (let i = 0; i < this.propertyValueList.length; i++) {
let currentPv: PropertyValue = this.propertyValueList[i];
if (currentPv.Name === pv.Name) {
pv = mergeIfRequired(pv, currentPv);
setPropertyValueAt(pv, i);
return this;
}
}
this.propertyValueList.push(pv);
return this;
}
}

View File

@ -0,0 +1,18 @@
import { PropertyKeyType } from '@overflow/commons/core/type';
export class PropertyValue {
private readonly name: PropertyKeyType;
private readonly value: any;
public constructor(name: PropertyKeyType, value: any) {
this.name = name;
this.value = value;
}
public get Name(): PropertyKeyType {
return this.name;
}
public get Value(): any {
return this.value;
}
}

View File

@ -4,12 +4,10 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';
export interface ActionMappingAnnotationAttributes { export interface ActionMappingAnnotationAttributes {
value: string[]; value: string[];
} }

View File

@ -4,7 +4,6 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';

View File

@ -4,7 +4,6 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';

View File

@ -4,7 +4,6 @@ import {
} from '@overflow/commons/core/reflect'; } from '@overflow/commons/core/reflect';
import { import {
MetadataKeyType,
PropertyKeyType, PropertyKeyType,
TypeUtil, TypeUtil,
} from '@overflow/commons/core/type'; } from '@overflow/commons/core/type';

View File

@ -17,7 +17,7 @@ import {
import { Class } from '@overflow/commons/core/reflect'; import { Class } from '@overflow/commons/core/reflect';
import { Action } from './action'; import { Action } from './action';
export default class DispatchReducer { export class DispatcherReducer {
private reducerMap: Map<string, any[]>; private reducerMap: Map<string, any[]>;

View File

@ -0,0 +1,2 @@
export * from './action';
export * from './dispatcher_reducer';

View File

@ -1,8 +1,14 @@
import { ConstructorType } from '@overflow/commons/core/type'; export * from './injectables';
export * from './reducer_configuration';
export * from './rest_api_configuration';
export * from './rpc_api_configuration';
export * from './webapp_configuration';
import { ClassType } from '@overflow/commons/core/type';
import MemberReducer from '@overflow/modules/member/reducer/member_reducer'; import MemberReducer from '@overflow/modules/member/reducer/member_reducer';
const reducers: ConstructorType[] = [ const reducers: ClassType[] = [
MemberReducer, MemberReducer,
]; ];
@ -12,7 +18,7 @@ const state: any = {
export interface ReduxConfig { export interface ReduxConfig {
state: any; state: any;
reducers: ConstructorType[]; reducers: ClassType[];
} }
const reduxConfig: ReduxConfig = { const reduxConfig: ReduxConfig = {

View File

@ -0,0 +1,22 @@
import { InjectablesType } from '@overflow/commons/application/decorators';
import { WebAppDispatcherReducer } from '../redux';
export const injectables: InjectablesType = [
WebAppDispatcherReducer,
{
injectType: WebAppDispatcherReducer,
injectableType: WebAppDispatcherReducer,
},
{
injectType: WebAppDispatcherReducer,
injectableFactory: function(): any {
return new WebAppDispatcherReducer();
},
},
{
injectName: 'Name',
injectableValue: 'TestValue',
},
];

View File

@ -0,0 +1,21 @@
import {
Store,
} from 'redux';
import {
Configuration,
} from '@overflow/commons/application/decorators';
import {
Injectable,
} from '@overflow/commons/di/decorators';
@Configuration()
export class ReducerConfiguration {
@Injectable()
public store(): Store<any> {
return null;
}
}

View File

@ -0,0 +1,7 @@
import { Configuration } from '@overflow/commons/application/decorators';
@Configuration()
export class RestAPIConfiguration {
}

View File

@ -0,0 +1,7 @@
import { Configuration } from '@overflow/commons/application/decorators';
@Configuration()
export class RpcAPIConfiguration {
}

View File

@ -0,0 +1,7 @@
import { Configuration } from '@overflow/commons/application/decorators';
@Configuration()
export class WebAppConfiguration {
}

View File

@ -28,11 +28,18 @@ import {
AppContainer, AppContainer,
} from 'react-hot-loader'; } from 'react-hot-loader';
import { Application } from '@overflow/commons/application';
import { WebApplication } from '@overflow/commons/application/decorators'; import { WebApplication } from '@overflow/commons/application/decorators';
import { Inject } from '@overflow/commons/di/decorators'; import { Inject } from '@overflow/commons/di/decorators';
import config from './config'; import config, {
import WebAppDispatchReducer from './redux/webapp_dispatch_reducer'; injectables,
ReducerConfiguration,
RestAPIConfiguration,
RpcAPIConfiguration,
WebAppConfiguration,
} from './config';
import {WebAppDispatcherReducer} from './redux';
import WebApp from './pages/webapp'; import WebApp from './pages/webapp';
// declare let module: { hot: any }; // declare let module: { hot: any };
@ -46,11 +53,12 @@ declare global {
} }
@WebApplication({ @WebApplication({
injectables: [ injectables: injectables,
WebAppDispatchReducer,
],
configurations: [ configurations: [
ReducerConfiguration,
RestAPIConfiguration,
RpcAPIConfiguration,
WebAppConfiguration,
], ],
}) })
class WebAppApplication { class WebAppApplication {
@ -62,7 +70,7 @@ class WebAppApplication {
private history: History; private history: History;
@Inject() @Inject()
private dispatchReducer: WebAppDispatchReducer; private dispatcherReducer: WebAppDispatcherReducer;
public constructor() { public constructor() {
this.container = document.getElementById('appContainer'); this.container = document.getElementById('appContainer');
@ -72,7 +80,7 @@ class WebAppApplication {
public async run(): Promise<void> { public async run(): Promise<void> {
try { try {
this.renderLoading(); this.renderLoading();
let reducer: WebAppDispatchReducer = new WebAppDispatchReducer(); let reducer: WebAppDispatcherReducer = new WebAppDispatcherReducer();
reducer.registerReducers(config.redux.reducers); reducer.registerReducers(config.redux.reducers);
this.store = createStore(reducer.reducer, config.redux.state); this.store = createStore(reducer.reducer, config.redux.state);
@ -179,4 +187,4 @@ class WebAppApplication {
} }
} }
WebAppApplication.main(); Application.run(WebAppApplication);

View File

@ -0,0 +1 @@
export * from './webapp_dispatch_reducer';

View File

@ -2,10 +2,10 @@ import {
Injectable, Injectable,
} from '@overflow/commons/di/decorators'; } from '@overflow/commons/di/decorators';
import DispatchReducer from '@overflow/commons/redux/dispatch_reducer'; import {DispatcherReducer} from '@overflow/commons/redux';
@Injectable() @Injectable()
export default class WebAppDispatchReducer extends DispatchReducer { export class WebAppDispatcherReducer extends DispatcherReducer {
public constructor() { public constructor() {
super(); super();
} }