tsioc
Version:
tsioc is AOP, Ioc container, via typescript decorator
159 lines (157 loc) • 7.47 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
var index_1 = require("../core/index");
var index_2 = require("../utils/index");
var index_3 = require("./decorators/index");
var AdviceMatcher = /** @class */ (function () {
function AdviceMatcher(container) {
this.container = container;
}
AdviceMatcher.prototype.match = function (aspectType, targetType, adviceMetas, instance) {
var _this = this;
var className = targetType.name;
adviceMetas = adviceMetas || index_1.getOwnMethodMetadata(index_3.Advice, targetType);
var aspectMgr = this.container.get(index_2.symbols.IAdvisor);
var matched = [];
if (targetType === aspectType) {
var adviceNames = Object.keys(adviceMetas);
if (adviceNames.length > 1) {
var advices_1 = [];
adviceNames.forEach(function (n) {
advices_1 = advices_1.concat(adviceMetas[n]);
});
adviceNames.forEach(function (n) {
advices_1.forEach(function (adv) {
if (adv.propertyKey !== n) {
if (_this.matchAspectSelf(n, adv)) {
matched.push({
name: n,
fullName: aspectType.name + "." + n,
advice: adv
});
}
}
});
});
}
}
else {
var points_1 = [];
var decorators_1 = Object.getOwnPropertyDescriptors(targetType.prototype);
// match method.
for (var name_1 in decorators_1) {
points_1.push({
name: name_1,
fullName: className + "." + name_1
});
}
var allmethods = index_1.getParamerterNames(targetType);
Object.keys(allmethods).forEach(function (name) {
if (name === 'constructor') {
return;
}
if (index_2.isUndefined(decorators_1[name])) {
points_1.push({
name: name,
fullName: className + "." + name
});
}
});
Object.getOwnPropertyNames(adviceMetas).forEach(function (name) {
var advices = adviceMetas[name];
advices.forEach(function (metadata) {
matched = matched.concat(_this.filterPointcut(targetType, points_1, metadata));
});
});
}
return matched;
};
AdviceMatcher.prototype.matchAspectSelf = function (name, metadata) {
if (metadata.pointcut) {
var pointcut = metadata.pointcut;
if (index_2.isString(pointcut)) {
if (/^execution\(\S+\)$/.test(pointcut)) {
pointcut = pointcut.substring(10, pointcut.length - 1);
return pointcut === name;
}
}
else if (index_2.isRegExp(pointcut)) {
return pointcut.test(name);
}
}
return false;
};
AdviceMatcher.prototype.filterPointcut = function (type, points, metadata) {
if (!metadata.pointcut) {
return [];
}
var matchedPointcut;
if (metadata.pointcut) {
var match_1 = this.matchTypeFactory(type, metadata.pointcut);
matchedPointcut = points.filter(function (p) { return match_1(p.name, p.fullName, p); });
}
matchedPointcut = matchedPointcut || [];
return matchedPointcut.map(function (p) {
return Object.assign({}, p, { advice: metadata });
});
};
AdviceMatcher.prototype.matchTypeFactory = function (type, pointcut) {
if (index_2.isString(pointcut)) {
pointcut = (pointcut || '').trim();
if (/^@annotation\(\S+\)$/.test(pointcut)) {
pointcut = pointcut.substring(12, pointcut.length - 1);
var annotation_1 = /^@/.test(pointcut) ? pointcut : ('@' + pointcut);
return function (name, fullName) { return index_1.hasOwnMethodMetadata(annotation_1, type, name) && !index_1.hasOwnClassMetadata(index_3.Aspect, type); };
}
else {
if (/^execution\(\S+\)$/.test(pointcut)) {
pointcut = pointcut.substring(10, pointcut.length - 1);
}
if (pointcut === '*' || pointcut === '*.*') {
return function (name, fullName, pointcut) { return !!name && !index_1.hasOwnClassMetadata(index_3.Aspect, type); };
}
pointcut = pointcut.replace(/\*\*/gi, '(\\\w+(\\\.|\\\/)){0,}\\\w+')
.replace(/\*/gi, '\\\w+')
.replace(/\./gi, '\\\.')
.replace(/\//gi, '\\\/');
var matcher_1 = new RegExp(pointcut + "$");
return function (name, fullName, pointcut) { return matcher_1.test(fullName); };
}
}
else if (index_2.isRegExp(pointcut)) {
var pointcutReg_1 = pointcut;
if (/^\^?@\w+/.test(pointcutReg_1.source)) {
return function (name, fullName, pointcut) {
var decName = Reflect.getMetadataKeys(type, name);
return decName.some(function (n) { return index_2.isString(n) && pointcutReg_1.test(n); });
};
}
else {
return function (name, fullName, pointcut) { return pointcutReg_1.test(fullName); };
}
}
return null;
};
AdviceMatcher.classAnnations = { "name": "AdviceMatcher", "params": { "constructor": ["container"], "match": ["aspectType", "targetType", "adviceMetas", "instance"], "matchAspectSelf": ["name", "metadata"], "filterPointcut": ["type", "points", "metadata"], "matchTypeFactory": ["type", "pointcut"] } };
AdviceMatcher = __decorate([
index_1.NonePointcut(),
index_1.Singleton(index_2.symbols.IAdviceMatcher),
__param(0, index_1.Inject(index_2.symbols.IContainer)),
__metadata("design:paramtypes", [Object])
], AdviceMatcher);
return AdviceMatcher;
}());
exports.AdviceMatcher = AdviceMatcher;
//# sourceMappingURL=sourcemaps/AdviceMatcher.js.map