node-web-mvc
Version:
node spring mvc
193 lines (192 loc) • 8.33 kB
JavaScript
"use strict";
/**
* @module TypeConverter
* @description 类型转换
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypedArray = void 0;
const SerializationCreateInstanceError_1 = __importDefault(require("../errors/SerializationCreateInstanceError"));
const ValueConvertError_1 = __importDefault(require("../errors/ValueConvertError"));
const Javascript_1 = __importDefault(require("../interface/Javascript"));
const RuntimeAnnotation_1 = __importDefault(require("../servlets/annotations/annotation/RuntimeAnnotation"));
const BasicTypeConverter_1 = require("./BasicTypeConverter");
const DateConverter_1 = __importDefault(require("./date/DateConverter"));
const JsonDeserialize_1 = __importDefault(require("./JsonDeserialize"));
const JsonFormat_1 = __importDefault(require("./JsonFormat"));
const ConvertPropertyTypeError_1 = __importDefault(require("../errors/ConvertPropertyTypeError"));
exports.TypedArray = Uint8Array.prototype.__proto__.constructor;
class TypeConverter {
createInstance(type, ...args) {
try {
if (!type) {
return null;
}
return new type(...args);
}
catch (ex) {
throw new SerializationCreateInstanceError_1.default(type, ex.message);
}
}
isInstanceof(v, type) {
return (typeof v === 'object' && !!v && v instanceof type);
}
convert(value, type, runtimeType) {
if (value === null || value === undefined) {
return null;
}
else if (!type) {
return value;
// throw new Error(`dataType not present`);
}
const clazzType = Javascript_1.default.createTyper(type);
if (runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.enum) {
return this.toEnum(value, type);
}
else if (clazzType.isType(BigInt)) {
return (0, BasicTypeConverter_1.toBigInt)(value);
}
else if (clazzType.isType(String)) {
return (0, BasicTypeConverter_1.toString)(value, type);
}
else if (clazzType.isType(Number)) {
return (0, BasicTypeConverter_1.toNumber)(value, type);
}
else if (clazzType.isType(Boolean)) {
return (0, BasicTypeConverter_1.toBoolean)(value);
}
else if (clazzType.isType(Date)) {
return (0, BasicTypeConverter_1.toDate)(value, type);
}
else if (clazzType.isType(Array)) {
return this.toArray(value, type, runtimeType);
}
else if (clazzType.isType(Set) || clazzType.isType(WeakSet)) {
return this.toSet(value, type, runtimeType);
}
else if (clazzType.isType(Map) || clazzType.isType(WeakMap)) {
return this.toMap(value, type, runtimeType);
}
else if (this.isInstanceof(value, type)) {
return value;
}
else if (clazzType.isType(exports.TypedArray)) {
return this.toTypedArray(value, type);
}
else if (runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.array) {
return this.toArray(value, Array, { args: [runtimeType], clazz: Array, name: 'Array', array: true, fullName: 'Array' });
}
else {
return this.toClass(value, type, runtimeType);
}
}
toEnum(value, type) {
if (value in type) {
return value;
}
throw new Error(`${value} is not enum value`);
}
toSet(value, type, runtimeType) {
var _a, _b;
const set = new type();
const items = value instanceof Array ? value : [value];
const itemType = (_b = (_a = runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.clazz;
items.forEach((value) => {
set.add(itemType ? this.convert(value, itemType) : value);
});
return set;
}
toMap(data, type, runtimeType) {
var _a, _b;
if (typeof data !== 'object' || !data || data instanceof Array) {
throw new ValueConvertError_1.default(data, Map);
}
const itemType = (_b = (_a = runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.args) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.clazz;
const map = new type();
Object.keys(data).forEach((key) => {
const value = itemType ? this.convert(data[key], itemType) : data[key];
map.set(key, value);
});
return map;
}
toArray(value, type, runtimeType) {
var _a, _b;
const values = value instanceof Array ? value : [value];
const itemType = (_b = (_a = runtimeType === null || runtimeType === void 0 ? void 0 : runtimeType.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.clazz;
const instance = this.createInstance(type);
if (value == null) {
return instance;
}
else if (itemType) {
values.forEach((item, i) => {
instance[i] = this.convert(item, itemType);
});
}
else {
values.forEach((item, i) => {
instance[i] = item;
});
}
return instance;
}
toTypedArray(data, type) {
return new type(data);
}
getDescriptor(instance, key) {
if (!instance)
return null;
return Object.getOwnPropertyDescriptor(instance, key) || Object.getOwnPropertyDescriptor(instance.__proto__, key);
}
toClass(data, dataType, runtimeType) {
// TODO: runtimeType补充
if (dataType === Object && (typeof data !== 'object' || !data)) {
return data;
}
const instance = this.createInstance(dataType);
const keys = Object.keys(data);
for (const key of keys) {
const value = data[key];
const descriptor = this.getDescriptor(instance, key) || {};
if (descriptor.writable === false || ('set' in descriptor && descriptor.set == undefined)) {
// 如果是只读属性
continue;
}
try {
instance[key] = this.handlePropertyValue(dataType, key, value);
}
catch (ex) {
throw new ConvertPropertyTypeError_1.default(key, ex);
}
}
return instance;
}
handlePropertyValue(clazz, name, value) {
var _a, _b, _c;
const basicProperty = RuntimeAnnotation_1.default.getPropertyAnnotations(clazz, name)[0];
if (!basicProperty) {
return value;
}
const deserializer = (_c = (_b = (_a = RuntimeAnnotation_1.default.getPropertyAnnotation(clazz, name, JsonDeserialize_1.default)) === null || _a === void 0 ? void 0 : _a.nativeAnnotation) === null || _b === void 0 ? void 0 : _b.getDeserializer) === null || _c === void 0 ? void 0 : _c.call(_b);
if (deserializer) {
// 自定义反序列化
return deserializer.deserialize(value, clazz, name);
}
const clazzType = basicProperty.dataType.clazz;
if (Javascript_1.default.createTyper(clazzType).isType(Date)) {
return this.handleDateProperty(clazz, clazzType, name, value);
}
const metaProperty = RuntimeAnnotation_1.default.getPropertyAnnotation(clazz, name, Object);
return this.convert(value, clazzType, metaProperty === null || metaProperty === void 0 ? void 0 : metaProperty.dataType);
}
handleDateProperty(clazz, dataType, name, value) {
const jsonFormat = RuntimeAnnotation_1.default.getPropertyAnnotation(clazz, name, JsonFormat_1.default);
if (!jsonFormat) {
return (0, BasicTypeConverter_1.toDate)(value, dataType);
}
const converter = DateConverter_1.default.of(jsonFormat.nativeAnnotation.pattern, jsonFormat.nativeAnnotation.locale);
return converter.parse(value);
}
}
exports.default = TypeConverter;