node-web-mvc
Version:
node spring mvc
161 lines (160 loc) • 6.5 kB
JavaScript
"use strict";
/**
* 注解索引,用于快速获取指定类下相关注解
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Javascript_1 = __importDefault(require("../../../interface/Javascript"));
const ElementType_1 = __importDefault(require("./ElementType"));
const annotationsSymbol = Symbol('annotations');
const mapAnnotationsSymbol = Symbol('allAnnotations');
class AnnotationIndexer {
static createIndexerIfNeed(ctor) {
if (!this.getIndexer(ctor)) {
const indexer = new AnnotationIndexer();
Javascript_1.default.defineHiddenProperty(ctor, annotationsSymbol, indexer);
indexer.owner = ctor;
}
return ctor[annotationsSymbol];
}
static getIndexer(ctor) {
if (!ctor || !ctor.hasOwnProperty(annotationsSymbol)) {
return null;
}
// 这里为了防止从原型链上找annotationsSymbol 所以采用hasOwnProperty
return ctor[annotationsSymbol];
}
static getMethodIndexer(clazz, method) {
var _a, _b, _c;
const indexer = this.getIndexer(clazz);
const key = typeof method == 'string' ? (_a = clazz.prototype) === null || _a === void 0 ? void 0 : _a[method] : method;
return (_c = (_b = indexer === null || indexer === void 0 ? void 0 : indexer.methods) === null || _b === void 0 ? void 0 : _b.get) === null || _c === void 0 ? void 0 : _c.call(_b, key);
}
constructor() {
this.clazz = new Map();
this.properties = {};
this.methods = new Map();
}
createMethodIndexer(methodKey) {
let method = this.methods.get(methodKey);
if (!method) {
method = {
annotations: new Map(),
parameters: {},
};
this.methods.set(methodKey, method);
}
return method;
}
cacheAnnotation(map, key, annotation) {
let annotations = map.get(key);
let allAnnotations = map[mapAnnotationsSymbol];
if (!annotations) {
annotations = [];
map.set(key, annotations);
}
if (!allAnnotations) {
allAnnotations = [];
Javascript_1.default.defineHiddenProperty(map, mapAnnotationsSymbol, allAnnotations);
}
allAnnotations.push(annotation);
annotations.push(annotation);
}
addAnnotation(annotation) {
const cacheKey = annotation.nativeAnnotation.constructor;
switch (annotation.elementType) {
case ElementType_1.default.TYPE:
this.cacheAnnotation(this.clazz, cacheKey, annotation);
break;
case ElementType_1.default.METHOD:
this.cacheAnnotation(this.createMethodIndexer(annotation.method).annotations, cacheKey, annotation);
break;
case ElementType_1.default.PROPERTY:
{
const name = annotation.name;
let properties = this.properties[name];
if (!properties) {
properties = this.properties[name] = new Map();
}
this.cacheAnnotation(properties, cacheKey, annotation);
}
case ElementType_1.default.PARAMETER:
{
const paramName = annotation.paramName;
const method = this.createMethodIndexer(annotation.method);
let parameter = method.parameters[paramName];
if (!parameter) {
parameter = method.parameters[paramName] = new Map();
}
this.cacheAnnotation(parameter, cacheKey, annotation);
}
}
}
static getClazzAnnotation(clazz, annotationType) {
const indexer = this.getIndexer(clazz);
if (indexer) {
return this.findAnnotation(indexer.clazz, annotationType);
}
}
static getMethodAnnotation(clazz, methodKey, annotationType) {
const indexer = this.getMethodIndexer(clazz, methodKey);
if (indexer) {
return this.findAnnotation(indexer.annotations, annotationType);
}
}
static getPropertyAnnotation(clazz, name, annotationType) {
var _a;
const indexer = this.getIndexer(clazz);
const property = (_a = indexer === null || indexer === void 0 ? void 0 : indexer.properties) === null || _a === void 0 ? void 0 : _a[name];
if (property) {
return this.findAnnotation(property, annotationType);
}
}
static getParameterAnnotation(clazz, methodKey, paramName, annotationType) {
var _a, _b;
const parameter = (_b = (_a = this.getMethodIndexer(clazz, methodKey)) === null || _a === void 0 ? void 0 : _a.parameters) === null || _b === void 0 ? void 0 : _b[paramName];
if (parameter) {
return this.findAnnotation(parameter, annotationType);
}
;
}
static findAnnotation(info, annotationType) {
const annotations = info[mapAnnotationsSymbol];
const len = arguments.length;
const cacheKey = (annotationType === null || annotationType === void 0 ? void 0 : annotationType.NativeAnnotation) || annotationType;
if (!annotations) {
return null;
}
if (len == 1) {
return annotations[0];
}
else if (info.get(cacheKey)) {
return info.get(cacheKey)[0];
}
else {
return annotations.find((m) => this.isAnnotationTypeOf(m, annotationType));
}
}
static findAnnotations(info, annotationType) {
const annotations = info[mapAnnotationsSymbol];
const len = arguments.length;
if (!annotations) {
return null;
}
if (len == 1) {
return annotations;
}
else {
return annotations.filter((m) => this.isAnnotationTypeOf(m, annotationType));
}
}
static isAnnotationTypeOf(m, type) {
const nativeAnnotation = m.nativeAnnotation;
const NativeAnnotation = type.NativeAnnotation;
return nativeAnnotation instanceof type || (NativeAnnotation && nativeAnnotation instanceof NativeAnnotation);
}
;
}
exports.default = AnnotationIndexer;