Skip to content

Commit ac19de2

Browse files
Dragan AndonovskiDragan Andonovski
authored andcommitted
[#56] Metadata Decorator Refactoring
- refactored the @EnableCaching, @Profile, @qualifier, @RequestMapping and @view decorators [work-in-progress]
1 parent 2a4d9fb commit ac19de2

12 files changed

+82
-55
lines changed

src/lib/decorators/ComponentDecorator.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InjectionDataDecoratorMetadata } from "./InjectionDecorators";
1+
import {InjectionDataDecoratorMetadata, Inject} from "./InjectionDecorators";
22
import { Interceptor } from "./InterceptorDecorator";
33
import {
44
ComponentDefinitionPostProcessor
@@ -14,7 +14,7 @@ import { DecoratorMetadata } from "./common/DecoratorMetadata";
1414
export class ComponentDecoratorMetadata extends DecoratorMetadata<ComponentDecoratorMetadata> {
1515
componentName: string;
1616
classToken: symbol;
17-
aliasTokens: Array<symbol>;
17+
aliasTokens: Array<Symbol>;
1818
injectionData: InjectionDataDecoratorMetadata;
1919
profiles: Array<string>;
2020

@@ -67,7 +67,7 @@ export class ComponentUtil {
6767
}
6868

6969
static getInjectionData(target): InjectionDataDecoratorMetadata {
70-
return this.getComponentData(target).injectionData;
70+
return DecoratorHelper.getMetadata(target, Inject, new InjectionDataDecoratorMetadata());
7171
}
7272

7373
static isController(target): boolean {

src/lib/decorators/EnableCachingDecorator.ts

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/lib/decorators/InjectionDecorators.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import { DecoratorType, DecoratorUtil } from "../helpers/DecoratorUtils";
55
import "reflect-metadata";
66
import { DecoratorHelper } from "./common/DecoratorHelper";
77
import { DecoratorMetadata } from "./common/DecoratorMetadata";
8-
import { Decorator } from "./common/DecoratorDefinition";
98

10-
const INJECT_DECORATOR_TOKEN = Symbol('injector_decorator_token');
119

1210
export class DependencyData {
1311
token: Symbol;
@@ -65,13 +63,13 @@ export function Autowired() {
6563
};
6664
}
6765

68-
export function Value(preopertyKey) {
66+
export function Value(propertyKey) {
6967
return function (target: any, fieldName: string) {
7068
DecoratorUtil.throwOnWrongType(Value, DecoratorType.PROPERTY, [...arguments]);
7169

72-
let injectionData = DecoratorHelper.getOwnMetadata(target, Value, new InjectionDataDecoratorMetadata(), true);
73-
injectionData.properties.set(fieldName, preopertyKey);
74-
DecoratorHelper.setMetadata(target, Value, injectionData);
70+
let injectionData = DecoratorHelper.getOwnMetadata(target, Inject, new InjectionDataDecoratorMetadata(), true);
71+
injectionData.properties.set(fieldName, propertyKey);
72+
DecoratorHelper.setMetadata(target, Inject, injectionData);
7573
};
7674
}
7775
DecoratorHelper.createDecorator(Value, DecoratorType.PROPERTY);
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
1-
import { ComponentUtil } from "./ComponentDecorator";
2-
import { ConfigurationUtil } from "./ConfigurationDecorator";
1+
import {ComponentUtil, ComponentDecoratorMetadata, Component} from "./ComponentDecorator";
2+
import {ConfigurationUtil, Configuration, ConfigurationDecoratorMetadata} from "./ConfigurationDecorator";
33
import { DecoratorUtil, DecoratorType } from "../helpers/DecoratorUtils";
4+
import {DecoratorHelper} from "./common/DecoratorHelper";
45

56
export function Profile(...profiles: Array<string>) {
67
return function (target) {
78
DecoratorUtil.throwOnWrongType(Profile, DecoratorType.CLASS, [...arguments]);
89
ComponentUtil.throwWhenNotOnComponentClass(Profile, [...arguments]);
9-
profiles.forEach((profile) => ComponentUtil.getComponentData(target).profiles.push(profile));
10+
profiles.forEach((profile) => {
11+
let componentDecoratorMetadata = <ComponentDecoratorMetadata> DecoratorHelper.getOwnMetadata(target, Component);
12+
componentDecoratorMetadata.profiles.push(profile);
13+
DecoratorHelper.setMetadata(target, Component, componentDecoratorMetadata);
14+
});
1015
};
1116
}
1217

1318
export function ActiveProfiles(...profiles: Array<string>) {
1419
return function (target) {
1520
DecoratorUtil.throwOnWrongType(ActiveProfiles, DecoratorType.CLASS, [...arguments]);
1621
ConfigurationUtil.throwWhenNotOnConfigurationClass(ActiveProfiles, [...arguments]);
17-
ConfigurationUtil.getConfigurationData(target).activeProfiles.push(...profiles);
22+
let configurationDecoratorMetadata = <ConfigurationDecoratorMetadata> DecoratorHelper.getMetadata(target, Configuration);
23+
configurationDecoratorMetadata.activeProfiles.push(...profiles);
24+
DecoratorHelper.setMetadata(target, Configuration, configurationDecoratorMetadata);
1825
};
1926
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { ComponentUtil } from "./ComponentDecorator";
1+
import {ComponentUtil, Component, ComponentDecoratorMetadata} from "./ComponentDecorator";
22
import { DecoratorType, DecoratorUtil } from "../helpers/DecoratorUtils";
3+
import {DecoratorHelper} from "./common/DecoratorHelper";
34

45
export function Qualifier(token: Symbol) {
56
return function (target) {
67
DecoratorUtil.throwOnWrongType(Qualifier, DecoratorType.CLASS, [...arguments]);
78
ComponentUtil.throwWhenNotOnComponentClass(Qualifier, [...arguments]);
8-
ComponentUtil.getAliasTokens(target).push(token);
9+
10+
let componentDecoratorMetadata = <ComponentDecoratorMetadata> DecoratorHelper.getOwnMetadata(target, Component);
11+
componentDecoratorMetadata.aliasTokens.push(token);
12+
DecoratorHelper.setMetadata(target, Component, componentDecoratorMetadata);
913
};
1014
}

src/lib/decorators/RequestMappingDecorator.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import * as _ from "lodash";
22
import { DecoratorUtil, DecoratorType } from "../helpers/DecoratorUtils";
33
import { DecoratorUsageTypeError } from "../errors/DecoratorUsageErrors";
44
import { BadArgumentError } from "../errors/BadArgumentErrors";
5+
import {StandaloneDecoratorMetadata} from "./common/DecoratorMetadata";
6+
import {DecoratorHelper} from "./common/DecoratorHelper";
57

68
// NOTE: These are methods defined on the Express Router
79
// http://expressjs.com/en/4x/api.html#router
@@ -41,6 +43,24 @@ export class RouterConfig {
4143
routes: Array<RouterConfigItem> = [];
4244
}
4345

46+
export class RequestMappingDecoratorMetadata extends StandaloneDecoratorMetadata<RequestMappingDecoratorMetadata> {
47+
routes: Array<RouterConfigItem>;
48+
path: string;
49+
50+
constructor() {
51+
super();
52+
this.path = "";
53+
this.routes = [];
54+
}
55+
56+
setPath(path: string) {
57+
this.routes.forEach((value, index) => {
58+
let routePath = path + value.requestConfig.path;
59+
value.requestConfig.path = routePath;
60+
});
61+
}
62+
}
63+
4464
export function RequestMapping(config: RequestMappingConfig) {
4565
return function (...args) {
4666
let type = DecoratorUtil.getType(args);
@@ -52,39 +72,38 @@ export function RequestMapping(config: RequestMappingConfig) {
5272
(`When using @${RequestMapping.name} on methods you must provide the request method type`);
5373
}
5474
let method = args[1];
55-
let routerConfig = RequestMappingUtil.initRouterConfigIfDoesntExist(target);
75+
let routerConfig = DecoratorHelper.getOwnMetadata(target, RequestMapping, new RequestMappingDecoratorMetadata(), true);
5676
let routeConfig = _.find(routerConfig.routes, {methodHandler: method});
5777
// TODO: Override bug #51
5878
if (routeConfig) {
5979
routeConfig.requestConfig = config;
6080
} else {
6181
routerConfig.routes.push(new RouterConfigItem(config, method));
6282
}
83+
DecoratorHelper.setMetadata(target, RequestMapping, routerConfig);
6384
} else if (type === DecoratorType.CLASS) {
6485
// TODO: refactor when new options are added on @RequestMapping for classes
65-
target[CLASS_ROUTER_CONFIG] = config.path;
86+
let decoratorMetadata: RequestMappingDecoratorMetadata =
87+
DecoratorHelper.getOwnMetadata(target, RequestMapping, new RequestMappingDecoratorMetadata());
88+
decoratorMetadata.path = config.path;
89+
decoratorMetadata.setPath(config.path);
90+
DecoratorHelper.setMetadata(target, RequestMapping, decoratorMetadata);
6691
} else {
6792
let subjectName = DecoratorUtil.getSubjectName(args);
6893
throw new DecoratorUsageTypeError(RequestMapping, "classes and methods", subjectName);
6994
}
7095
};
7196
}
97+
DecoratorHelper.createDecorator(RequestMapping, DecoratorType.CLASS, DecoratorType.METHOD);
7298

7399
export class RequestMappingUtil {
74100

75101
static getValidRoutes(target): Array<RouterConfigItem> {
76-
let routerConfig = this.initRouterConfigIfDoesntExist(target.prototype);
102+
let routerConfig = DecoratorHelper.getMetadata(target, RequestMapping, new RequestMappingDecoratorMetadata());
77103
return _.filter(routerConfig.routes, (route) => route.isValid());
78104
}
79105

80-
static initRouterConfigIfDoesntExist(target): RouterConfig {
81-
if (_.isUndefined(target[ROUTER_CONFIG])) {
82-
target[ROUTER_CONFIG] = new RouterConfig();
83-
}
84-
return target[ROUTER_CONFIG];
85-
}
86-
87106
static getControllerRequestMappingPath(target) {
88-
return target[CLASS_ROUTER_CONFIG] || "";
107+
return DecoratorHelper.getMetadata(target, RequestMapping, new RequestMappingDecoratorMetadata());
89108
}
90109
}

src/lib/decorators/ViewDecorator.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import * as _ from "lodash";
2-
import { RequestMappingUtil, RouterConfigItem } from "../decorators/RequestMappingDecorator";
2+
import {
3+
RequestMappingUtil, RouterConfigItem, RequestMapping,
4+
RequestMappingDecoratorMetadata
5+
} from "../decorators/RequestMappingDecorator";
36
import { DecoratorUtil, DecoratorType } from "../helpers/DecoratorUtils";
7+
import {DecoratorHelper} from "./common/DecoratorHelper";
48

59
export function View(name?: string) {
610
return function (target, methodName) {
711
DecoratorUtil.throwOnWrongType(View, DecoratorType.METHOD, [...arguments]);
812
let viewName = name || methodName;
9-
let routerConfig = RequestMappingUtil.initRouterConfigIfDoesntExist(target);
13+
let routerConfig = DecoratorHelper.getOwnMetadata(target, RequestMapping, new RequestMappingDecoratorMetadata(), true);
14+
// TODO: fix this with the refactoring
1015
let routeConfig = _.find(routerConfig.routes, {methodHandler: methodName});
1116
if (!routeConfig) {
1217
// NOTE: in case when @View is before @RequestMapping

src/lib/decorators/aspect/AroundDecorator.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export class ProceedingJoinPoint {
2626
}
2727

2828
async proceed(): Promise<any> {
29-
let result = await Promise.race([Reflect.apply(this.methodRef, this.thisArg, this.args)]);
30-
return result;
29+
return await Promise.race([Reflect.apply(this.methodRef, this.thisArg, this.args)]);
3130
}
3231
}

src/lib/decorators/cache/EnableCachingDecorator.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {ConfigurationUtil} from "../ConfigurationDecorator";
2-
import {CacheDefinitionPostProcessor} from '../../processors/cache/CacheDefinitionPostProcessor';
32
import { DecoratorType, DecoratorUtil } from "../../helpers/DecoratorUtils";
3+
import {StandaloneDecoratorMetadata} from "../common/DecoratorMetadata";
4+
import {DecoratorHelper} from "../common/DecoratorHelper";
45

56
/**
67
*
@@ -12,7 +13,11 @@ export function EnableCaching() {
1213
DecoratorUtil.throwOnWrongType(EnableCaching, DecoratorType.CLASS, [...arguments]);
1314
ConfigurationUtil.throwWhenNotOnConfigurationClass(EnableCaching, [...arguments]);
1415

15-
ConfigurationUtil.getConfigurationData(target).componentDefinitionPostProcessorFactory.components
16-
.push(CacheDefinitionPostProcessor);
16+
DecoratorHelper.setMetadata(target, EnableCaching, new EnableCacheDecoratorMetadata());
1717
};
18+
}
19+
DecoratorHelper.createDecorator(EnableCaching, DecoratorType.CLASS);
20+
21+
export class EnableCacheDecoratorMetadata extends StandaloneDecoratorMetadata<EnableCacheDecoratorMetadata> {
22+
1823
}

src/lib/di/ApplicationContext.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
import {DynamicDependencyResolver} from "./DynamicDependencyResolver";
2323
import { CacheDefinitionPostProcessor } from "../processors/cache/CacheDefinitionPostProcessor";
2424
import { LoggerFactory } from "../helpers/logging/LoggerFactory";
25+
import {DecoratorHelper} from "../decorators/common/DecoratorHelper";
26+
import {EnableCaching} from "../decorators/cache/EnableCachingDecorator";
2527

2628
let logger = LoggerFactory.getInstance();
2729

@@ -40,6 +42,8 @@ export class ApplicationContext {
4042
private configurationData: ConfigurationDecoratorMetadata;
4143
private unRegisterExitListenerCallback: Function;
4244

45+
private configurationClass;
46+
4347
constructor(configurationClass) {
4448
this.state = ApplicationContextState.NOT_INITIALIZED;
4549
logger.info('Constructing the application context...');
@@ -48,6 +52,8 @@ export class ApplicationContext {
4852
this.configurationData = ConfigurationUtil.getConfigurationData(configurationClass);
4953
this.initializeEnvironment();
5054
this.configurationData.loadAllComponents(this.environment);
55+
56+
this.configurationClass = configurationClass;
5157
}
5258

5359
getComponent <T>(componentClass): T {
@@ -112,8 +118,7 @@ export class ApplicationContext {
112118
}
113119

114120
private wireCacheDefinitionPostProcessor() {
115-
if (this.configurationData.componentDefinitionPostProcessorFactory
116-
.components.indexOf(CacheDefinitionPostProcessor) !== -1) {
121+
if (DecoratorHelper.hasMetadata(this.configurationClass, EnableCaching)){
117122
let cacheDefinitionPostProcessor = <CacheDefinitionPostProcessor>
118123
this.injector.getComponent(ComponentUtil.getClassToken(CacheDefinitionPostProcessor));
119124
cacheDefinitionPostProcessor.setInjector(this.injector);
@@ -200,6 +205,8 @@ export class ApplicationContext {
200205
logger.verbose('Initializing component definition post processors...');
201206
// NOTE: add custom defined component definition post processors
202207
this.configurationData.componentDefinitionPostProcessorFactory.components.push(AspectDefinitionPostProcessor);
208+
if (DecoratorHelper.hasMetadata(this.configurationClass, EnableCaching))
209+
this.configurationData.componentDefinitionPostProcessorFactory.components.push(CacheDefinitionPostProcessor);
203210

204211
// NOTE: initialize all component definition post processors
205212
for (let CompConstructor of this.getActiveDefinitionPostProcessors()) {

src/lib/helpers/ReflectUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export class ReflectUtils {
3333
allSymbols = allSymbols.concat(Object.getOwnPropertySymbols(target));
3434
} else {
3535
allSymbols = Object.getOwnPropertySymbols(target);
36-
allSymbols = allSymbols.concat(Object.getOwnPropertySymbols(target.prototype));
36+
if (target.prototype !== undefined)
37+
allSymbols = allSymbols.concat(Object.getOwnPropertySymbols(target.prototype));
3738
}
3839
if (allSymbols.indexOf(token) !== -1) {
3940
return target[token] || target.prototype[token];

src/lib/web/Dispatcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export class Dispatcher {
3838
logger.debug(`Registering controller ${ComponentUtil.getComponentData(clazz).componentName}.`);
3939
let controllerMappingPath = RequestMappingUtil.getControllerRequestMappingPath(clazz);
4040
for (let route of RequestMappingUtil.getValidRoutes(clazz)) {
41-
route.requestConfig.path = controllerMappingPath + route.requestConfig.path;
41+
// route.requestConfig.path = controllerMappingPath + route.requestConfig.path;
4242
this.routerConfigurer.registerHandler(route, instance);
4343
}
4444
}

0 commit comments

Comments
 (0)