feat: add node-shim & move plugin interface
Signed-off-by: MiaoWoo <admin@yumc.pw>
This commit is contained in:
parent
79f151de5c
commit
73ada5fd17
@ -26,7 +26,8 @@ export namespace plugin {
|
|||||||
enable(...args: any[]): void;
|
enable(...args: any[]): void;
|
||||||
disable(...args: any[]): void;
|
disable(...args: any[]): void;
|
||||||
reload(...args: any[]): void;
|
reload(...args: any[]): void;
|
||||||
getPlugins(): Map<string, any>;
|
getPlugin(name: string): plugin.Plugin;
|
||||||
|
getPlugins(): Map<string, plugin.Plugin>;
|
||||||
}
|
}
|
||||||
export interface Plugin {
|
export interface Plugin {
|
||||||
description: PluginMetadata;
|
description: PluginMetadata;
|
||||||
|
@ -1,196 +1,204 @@
|
|||||||
|
/// <reference types="@ccms/types/dist/typings/jdk" />
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反射工具类
|
* 反射工具类
|
||||||
* Created by MiaoWoo on 2017/2/9 0009.
|
* Created by MiaoWoo on 2017/2/9 0009.
|
||||||
*/
|
*/
|
||||||
const JavaClass = Java.type('java.lang.Class');
|
const JavaClass = Java.type('java.lang.Class')
|
||||||
const JavaObject = Java.type('java.lang.Object')
|
const JavaObject = Java.type('java.lang.Object')
|
||||||
const NoSuchFieldException = Java.type('java.lang.NoSuchFieldException');
|
const NoSuchFieldException = Java.type('java.lang.NoSuchFieldException')
|
||||||
const methodCache = [];
|
const methodCache = []
|
||||||
|
|
||||||
class Reflect {
|
class Reflect {
|
||||||
private obj: any;
|
private obj: java.lang.Object
|
||||||
private class: any
|
private class: java.lang.Class
|
||||||
|
|
||||||
constructor(obj: any) {
|
constructor(obj: any) {
|
||||||
// if (obj === undefined || obj === null) { throw Error(`reflect object can't be ${obj}!`) }
|
// if (obj === undefined || obj === null) { throw Error(`reflect object can't be ${obj}!`) }
|
||||||
if (obj instanceof JavaClass) {
|
if (obj instanceof JavaClass) {
|
||||||
this.obj = null;
|
this.obj = null
|
||||||
this.class = obj;
|
this.class = obj
|
||||||
} else {
|
} else {
|
||||||
this.obj = obj;
|
this.obj = obj
|
||||||
if (obj !== null && obj !== undefined && obj.class) {
|
if (obj !== null && obj !== undefined && obj.class) {
|
||||||
this.class = obj.class;
|
this.class = obj.class
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method(...args: any[]) {
|
method(name: string, ...args: any[]) {
|
||||||
return declaredMethod(this.class, args[0], types(args.slice(1)));
|
return declaredMethod(this.class, name, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
methods() {
|
methods() {
|
||||||
return Java.from(declaredMethods(this.class));
|
return Java.from(declaredMethods(this.class))
|
||||||
}
|
}
|
||||||
|
|
||||||
field(name): Reflect {
|
field(name: string | java.lang.String): Reflect {
|
||||||
try {
|
try {
|
||||||
// Try getting a public field
|
// Try getting a public field
|
||||||
let field = this.class.field(name);
|
let field = this.class.getField(name)
|
||||||
return on(field.get(this.obj));
|
return on(field.get(this.obj))
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
// Try again, getting a non-public field
|
// Try again, getting a non-public field
|
||||||
return on(accessible(declaredField(this.class, name)).get(this.obj));
|
return on(accessible(declaredField(this.class, name)).get(this.obj))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
fields(declared = false) {
|
fields(declared = false): java.lang.reflect.Field[] {
|
||||||
return Java.from(declared ? this.class.declaredFields : this.class.fields);
|
return Java.from(declared ? this.class.getDeclaredFields() : this.class.getFields())
|
||||||
}
|
}
|
||||||
|
|
||||||
values(declared = false) {
|
values(declared = false) {
|
||||||
let cache = {};
|
return this.fields(declared).reduce((cache, field) => { return cache[field.getName()] = this.field(field.getName()).get() }, {}) as any
|
||||||
this.fields(declared).forEach(fed => cache[fed.name] = this.field(fed.name).get())
|
|
||||||
return cache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
call(...args): Reflect {
|
call(...args: any[]): Reflect {
|
||||||
let params = args.slice(1);
|
let params = args.slice(1)
|
||||||
let method = accessible(declaredMethod(this.class, args[0], types(params)));
|
let method = accessible(declaredMethod(this.class, args[0], ...types(params)))
|
||||||
let result = method.invoke(this.get(), params);
|
let result = method.invoke(this.get(), params)
|
||||||
return result && on(result);
|
return result && on(result)
|
||||||
};
|
}
|
||||||
|
|
||||||
get(...args): Reflect | any {
|
get(): any
|
||||||
return args.length === 1 ? this.field(args[0]) : this.obj;
|
get(index: number, declared?: boolean): Reflect
|
||||||
};
|
get(prop: string): Reflect
|
||||||
|
get(param?: string | number, declared: boolean = true): Reflect | any {
|
||||||
|
if (param == undefined || param == null) return this.obj
|
||||||
|
if (typeof param == "number") {
|
||||||
|
return on(accessible(this.fields(declared)[param]).get(this.obj))
|
||||||
|
}
|
||||||
|
if (typeof param == "string") {
|
||||||
|
return this.field(param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// noinspection JSUnusedGlobalSymbols
|
set(name: any, value: any): Reflect {
|
||||||
set(name, value): Reflect {
|
accessible(declaredField(this.class, name)).set(this.obj, value)
|
||||||
accessible(declaredField(this.class, name)).set(this.obj, value);
|
return this
|
||||||
return this;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
create(...args): Reflect {
|
create(...args): Reflect {
|
||||||
return on(declaredConstructor(this.class, args).newInstance(args));
|
return on(declaredConstructor(this.class, args).newInstance(args))
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an array of types for an array of objects
|
* Get an array of types for an array of objects
|
||||||
*/
|
*/
|
||||||
function types(values, def?) {
|
function types(values: any[], def?: any) {
|
||||||
if (values === null) {
|
if (values === null) {
|
||||||
return [];
|
return []
|
||||||
}
|
}
|
||||||
let result: any[] = [];
|
let result: java.lang.Class[] = []
|
||||||
values.forEach(t => result.push((t || def) ? JavaObject.class : t instanceof JavaClass ? t : t.class));
|
values.forEach(t => result.push((t || def) ? JavaObject.class : t instanceof JavaClass ? t : t.class))
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function accessible(accessible) {
|
function accessible<T extends java.lang.reflect.AccessibleObject>(accessible: T): T {
|
||||||
if (accessible === null) {
|
if (accessible === null) {
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
if (!accessible.isAccessible()) {
|
if (!accessible.isAccessible()) {
|
||||||
accessible.setAccessible(true);
|
accessible.setAccessible(true)
|
||||||
}
|
}
|
||||||
return accessible;
|
return accessible
|
||||||
}
|
}
|
||||||
|
|
||||||
function declaredConstructor(clazz, param) {
|
function declaredConstructor(clazz, param) {
|
||||||
let constructor;
|
let constructor
|
||||||
try {
|
try {
|
||||||
constructor = clazz.getDeclaredConstructor(types(param));
|
constructor = clazz.getDeclaredConstructor(types(param))
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
try {
|
try {
|
||||||
constructor = clazz.getDeclaredConstructor(types(param, true));
|
constructor = clazz.getDeclaredConstructor(types(param, true))
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
constructor = clazz.getDeclaredConstructors()[0];
|
constructor = clazz.getDeclaredConstructors()[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return accessible(constructor);
|
return accessible(constructor)
|
||||||
}
|
}
|
||||||
|
|
||||||
function declaredField(clazz, name) {
|
function declaredField(clazz: java.lang.Class, name: string | java.lang.String) {
|
||||||
if (!clazz) { throw Error(`target class can't be ${clazz}!`) }
|
if (!clazz) { throw Error(`target class can't be ${clazz}!`) }
|
||||||
let target = clazz;
|
let target = clazz
|
||||||
let field = null;
|
let field = null
|
||||||
// noinspection JSUnresolvedVariable
|
// noinspection JSUnresolvedVariable
|
||||||
while (target !== JavaObject.class) {
|
while (target !== JavaObject.class) {
|
||||||
try {
|
try {
|
||||||
field = target.getDeclaredField(name);
|
field = target.getDeclaredField(name)
|
||||||
if (field !== null) { break; }
|
if (field !== null) { break }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (target === undefined) { break; }
|
if (target === undefined) { break }
|
||||||
target = target.getSuperclass();
|
target = target.getSuperclass()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (field === null) {
|
if (field === null) {
|
||||||
throw new NoSuchFieldException(name + " is not found in " + clazz.name);
|
throw new NoSuchFieldException(name + " is not found in " + clazz.getName())
|
||||||
}
|
}
|
||||||
return field;
|
return field
|
||||||
}
|
}
|
||||||
|
|
||||||
function declaredMethod(clazz, name, clazzs) {
|
function declaredMethod(clazz: java.lang.Class, name: string, ...clazzs: any[]): java.lang.reflect.Method {
|
||||||
let key = clazz.name + '.' + name + ':' + (clazzs || []).join(':');
|
let key = clazz.getName() + '.' + name + ':' + (clazzs || []).join(':')
|
||||||
if (!methodCache[key]) {
|
if (!methodCache[key]) {
|
||||||
try {
|
try {
|
||||||
methodCache[key] = clazz.getMethod(name, clazzs);
|
methodCache[key] = clazz.getMethod(name, clazzs as any)
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
try {
|
try {
|
||||||
methodCache[key] = clazz.getDeclaredMethod(name, clazzs);
|
methodCache[key] = clazz.getDeclaredMethod(name, clazzs as any)
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
for (const m of Java.from(declaredMethods(clazz))) {
|
for (const m of Java.from(declaredMethods(clazz))) {
|
||||||
if (m.name == name) {
|
if (m.name == name) {
|
||||||
methodCache[key] = m;
|
methodCache[key] = m
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return methodCache[key];
|
return methodCache[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
function declaredMethods(clazz) {
|
function declaredMethods(clazz) {
|
||||||
return clazz.declaredMethods;
|
return clazz.declaredMethods
|
||||||
}
|
}
|
||||||
|
|
||||||
let classMethodsCache: any[] = [];
|
let classMethodsCache: any[] = []
|
||||||
|
|
||||||
function mapToObject(javaObj) {
|
function mapToObject(javaObj) {
|
||||||
if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
|
if (!javaObj || !javaObj.class) { throw new TypeError(`参数 ${javaObj} 不是一个Java对象!`) }
|
||||||
let target = {};
|
let target = {}
|
||||||
getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t));
|
getJavaObjectMethods(javaObj).forEach(t => mapMethod(target, javaObj, t))
|
||||||
return target;
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJavaObjectMethods(javaObj) {
|
function getJavaObjectMethods(javaObj) {
|
||||||
let className = javaObj.class.name;
|
let className = javaObj.class.name
|
||||||
if (!classMethodsCache[className]) {
|
if (!classMethodsCache[className]) {
|
||||||
let names: any[] = [];
|
let names: any[] = []
|
||||||
let methods = javaObj.class.methods;
|
let methods = javaObj.class.methods
|
||||||
for (let i in methods) {
|
for (let i in methods) {
|
||||||
names.push(methods[i].name);
|
names.push(methods[i].name)
|
||||||
}
|
}
|
||||||
classMethodsCache[className] = names;
|
classMethodsCache[className] = names
|
||||||
}
|
}
|
||||||
return classMethodsCache[className];
|
return classMethodsCache[className]
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapMethod(target, source, name) {
|
function mapMethod(target, source, name) {
|
||||||
target[name] = function __SimpleDynamicMethod__(...args) {
|
target[name] = function __SimpleDynamicMethod__(...args) {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
return source[name](args);
|
return source[name](args)
|
||||||
} else {
|
} else {
|
||||||
return source[name]();
|
return source[name]()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function on(obj) {
|
function on(obj) {
|
||||||
// if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
|
// if (!obj || !obj.class) { throw new TypeError(`参数 ${obj} 不是一个Java对象!`) }
|
||||||
return new Reflect(obj);
|
return new Reflect(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
export = {
|
export = {
|
||||||
|
@ -54,6 +54,7 @@ class MiaoScriptCore {
|
|||||||
console.i18n("ms.core.engine.disable")
|
console.i18n("ms.core.engine.disable")
|
||||||
this.pluginManager.disable(this.pluginManager.getPlugins())
|
this.pluginManager.disable(this.pluginManager.getPlugins())
|
||||||
this.taskManager.disable()
|
this.taskManager.disable()
|
||||||
|
process.exit(0)
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
require.disable()
|
require.disable()
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/// <reference types="@ccms/nashorn" />
|
/// <reference types="@ccms/nashorn" />
|
||||||
|
|
||||||
import i18n from '@ccms/i18n'
|
import i18n from '@ccms/i18n'
|
||||||
let ployfillStartTime = new Date().getTime();
|
let ployfillStartTime = new Date().getTime()
|
||||||
i18n.initialize();
|
i18n.initialize()
|
||||||
console.i18n("ms.ployfill.initialize");
|
console.i18n("ms.ployfill.initialize")
|
||||||
require('./es5-ext');
|
require('./es5-ext')
|
||||||
require('core-js');
|
require('./node-shim')
|
||||||
require('./node-shim');
|
require('core-js')
|
||||||
global.setGlobal('Proxy', require('./proxy').Proxy)
|
global.setGlobal('Proxy', require('./proxy').Proxy)
|
||||||
global.setGlobal('XMLHttpRequest', require('./xml-http-request').XMLHttpRequest)
|
global.setGlobal('XMLHttpRequest', require('./xml-http-request').XMLHttpRequest)
|
||||||
global.setGlobal('Blob', require('blob-polyfill').Blob)
|
global.setGlobal('Blob', require('blob-polyfill').Blob)
|
||||||
console.i18n("ms.ployfill.completed", { time: (new Date().getTime() - ployfillStartTime) / 1000 });
|
console.i18n("ms.ployfill.completed", { time: (new Date().getTime() - ployfillStartTime) / 1000 })
|
||||||
|
@ -1,8 +1,36 @@
|
|||||||
global.setGlobal('process', {
|
import { EventEmitter } from 'events'
|
||||||
env: {
|
|
||||||
|
const Thread = Java.type('java.lang.Thread')
|
||||||
|
const ThreadGroup = Java.type("java.lang.ThreadGroup")
|
||||||
|
const AtomicInteger = Java.type("java.util.concurrent.atomic.AtomicInteger")
|
||||||
|
const ThreadPoolExecutor = Java.type('java.util.concurrent.ThreadPoolExecutor')
|
||||||
|
const LinkedBlockingQueue = Java.type("java.util.concurrent.LinkedBlockingQueue")
|
||||||
|
|
||||||
|
const threadCount = new AtomicInteger(0)
|
||||||
|
const threadGroup = new ThreadGroup("@ccms/ployfill-micro-task")
|
||||||
|
const microTaskPool = new ThreadPoolExecutor(
|
||||||
|
10, 100, 60, Packages.java.util.concurrent.TimeUnit.SECONDS,
|
||||||
|
new LinkedBlockingQueue(500),
|
||||||
|
(run: any) => new Thread(threadGroup, run, "@ccms/micro-task-" + threadCount.incrementAndGet()),
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||||
|
)
|
||||||
|
|
||||||
|
class Process extends EventEmitter {
|
||||||
|
env = {
|
||||||
__noSuchProperty__: (prop) => {
|
__noSuchProperty__: (prop) => {
|
||||||
return Packages.java.lang.System.getenv(prop)
|
return Packages.java.lang.System.getenv(prop)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
platform: Packages.java.lang.System.getProperty("os.name")
|
platform = Packages.java.lang.System.getProperty("os.name")
|
||||||
}, {})
|
nextTick(func: Function) {
|
||||||
|
microTaskPool.execute(func)
|
||||||
|
}
|
||||||
|
queueMicrotask(func: Function) {
|
||||||
|
microTaskPool.execute(func)
|
||||||
|
}
|
||||||
|
exit() {
|
||||||
|
microTaskPool.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global.setGlobal('process', new Process(), {})
|
||||||
|
global.setGlobal('queueMicrotask', (func: any) => microTaskPool.execute(func), {})
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { server, MiaoScriptConsole, event } from "@ccms/api";
|
import { server, MiaoScriptConsole, event, plugin } from "@ccms/api";
|
||||||
import { injectable, inject, postConstruct } from "@ccms/container";
|
import { injectable, inject, postConstruct } from "@ccms/container";
|
||||||
import { getPluginMetadata } from "./utils";
|
import { getPluginMetadata } from "./utils";
|
||||||
|
|
||||||
export namespace interfaces {
|
export namespace interfaces {
|
||||||
@injectable()
|
@injectable()
|
||||||
export abstract class Plugin {
|
export abstract class Plugin implements plugin.Plugin {
|
||||||
public description: PluginMetadata;
|
public description: PluginMetadata;
|
||||||
public logger: Console;
|
public logger: Console;
|
||||||
@inject(server.Console)
|
@inject(server.Console)
|
||||||
|
@ -26,8 +26,8 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
|
|
||||||
private initialized: boolean = false
|
private initialized: boolean = false
|
||||||
private pluginRequireMap: Map<string, any>
|
private pluginRequireMap: Map<string, any>
|
||||||
private pluginInstanceMap: Map<string, interfaces.Plugin>
|
private pluginInstanceMap: Map<string, plugin.Plugin>
|
||||||
private pluginMetadataMap: Map<string, interfaces.PluginMetadata>
|
private pluginMetadataMap: Map<string, plugin.PluginMetadata>
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") }
|
if (this.pluginInstance === undefined) { throw new Error("Can't found Plugin Instance!") }
|
||||||
@ -52,23 +52,27 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
this.buildPlugins()
|
this.buildPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
private logStage(plugin: interfaces.Plugin, stage: string) {
|
private logStage(plugin: plugin.Plugin, stage: string) {
|
||||||
console.i18n("ms.plugin.manager.stage", { stage, plugin: plugin.description.name, version: plugin.description.version, author: plugin.description.author })
|
console.i18n("ms.plugin.manager.stage", { stage, plugin: plugin.description.name, version: plugin.description.version, author: plugin.description.author })
|
||||||
}
|
}
|
||||||
|
|
||||||
private runPluginStage(plugin: interfaces.Plugin, stage: string, ext: Function) {
|
private runPluginStage(plugin: plugin.Plugin, stage: string, ext: Function) {
|
||||||
|
try {
|
||||||
this.logStage(plugin, i18n.translate(`ms.plugin.manager.stage.${stage}`))
|
this.logStage(plugin, i18n.translate(`ms.plugin.manager.stage.${stage}`))
|
||||||
ext()
|
ext()
|
||||||
this.runCatch(plugin, stage)
|
this.runCatch(plugin, stage)
|
||||||
this.runCatch(plugin, `${this.serverType}${stage}`)
|
this.runCatch(plugin, `${this.serverType}${stage}`)
|
||||||
this.execPluginStage(plugin, stage)
|
this.execPluginStage(plugin, stage)
|
||||||
|
} catch (ex) {
|
||||||
|
console.i18n("ms.plugin.manager.stage.exec.error", { plugin: plugin.description.name, executor: stage, error: ex })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从文件加载插件
|
* 从文件加载插件
|
||||||
* @param file java.io.File
|
* @param file java.io.File
|
||||||
*/
|
*/
|
||||||
loadFromFile(file: string): interfaces.Plugin {
|
loadFromFile(file: string): plugin.Plugin {
|
||||||
let metadata = this.loadPlugin(file)
|
let metadata = this.loadPlugin(file)
|
||||||
let plugin = this.buildPlugin(metadata && metadata.description ? metadata.description : this.pluginMetadataMap.get(file.toString()))
|
let plugin = this.buildPlugin(metadata && metadata.description ? metadata.description : this.pluginMetadataMap.get(file.toString()))
|
||||||
this.load(plugin)
|
this.load(plugin)
|
||||||
@ -77,7 +81,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
load(...args: any[]): void {
|
load(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
|
this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
|
||||||
this.runPluginStage(plugin, 'load', () => {
|
this.runPluginStage(plugin, 'load', () => {
|
||||||
this.loadConfig(plugin)
|
this.loadConfig(plugin)
|
||||||
})
|
})
|
||||||
@ -85,7 +89,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enable(...args: any[]): void {
|
enable(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
|
this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
|
||||||
this.runPluginStage(plugin, 'enable', () => {
|
this.runPluginStage(plugin, 'enable', () => {
|
||||||
this.registryCommand(plugin)
|
this.registryCommand(plugin)
|
||||||
this.registryListener(plugin)
|
this.registryListener(plugin)
|
||||||
@ -94,7 +98,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disable(...args: any[]): void {
|
disable(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => {
|
this.checkAndGet(args[0]).forEach((plugin: plugin.Plugin) => {
|
||||||
this.runPluginStage(plugin, 'disable', () => {
|
this.runPluginStage(plugin, 'disable', () => {
|
||||||
this.saveConfig(plugin)
|
this.saveConfig(plugin)
|
||||||
this.unregistryCommand(plugin)
|
this.unregistryCommand(plugin)
|
||||||
@ -104,12 +108,16 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reload(...args: any[]): void {
|
reload(...args: any[]): void {
|
||||||
this.checkAndGet(args[0]).forEach((pl: interfaces.Plugin) => {
|
this.checkAndGet(args[0]).forEach((pl: plugin.Plugin) => {
|
||||||
this.disable(pl)
|
this.disable(pl)
|
||||||
this.loadFromFile(pl.description.source)
|
this.loadFromFile(pl.description.source)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPlugin(name: string) {
|
||||||
|
return this.pluginInstanceMap.get(name)
|
||||||
|
}
|
||||||
|
|
||||||
getPlugins() {
|
getPlugins() {
|
||||||
return this.pluginInstanceMap
|
return this.pluginInstanceMap
|
||||||
}
|
}
|
||||||
@ -123,11 +131,11 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkAndGet(name: string | interfaces.Plugin | undefined | any): Map<string, interfaces.Plugin> | interfaces.Plugin[] {
|
private checkAndGet(name: string | plugin.Plugin | undefined | any): Map<string, plugin.Plugin> | plugin.Plugin[] {
|
||||||
if (name == this.pluginInstanceMap) { return this.pluginInstanceMap }
|
if (name == this.pluginInstanceMap) { return this.pluginInstanceMap }
|
||||||
if (typeof name == 'string' && this.pluginInstanceMap.has(name)) { return [this.pluginInstanceMap.get(name)] }
|
if (typeof name == 'string' && this.pluginInstanceMap.has(name)) { return [this.pluginInstanceMap.get(name)] }
|
||||||
if (name instanceof interfaces.Plugin) { return [name as interfaces.Plugin] }
|
if (name instanceof interfaces.Plugin) { return [name as plugin.Plugin] }
|
||||||
if (name.description || name.description.name) { return [name as interfaces.Plugin] }
|
if (name.description || name.description.name) { return [name as plugin.Plugin] }
|
||||||
throw new Error(`Plugin ${JSON.stringify(name)} not exist!`)
|
throw new Error(`Plugin ${JSON.stringify(name)} not exist!`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,12 +222,12 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private buildPlugin(metadata: interfaces.PluginMetadata) {
|
private buildPlugin(metadata: interfaces.PluginMetadata) {
|
||||||
let pluginInstance: interfaces.Plugin
|
let pluginInstance: plugin.Plugin
|
||||||
switch (metadata.type) {
|
switch (metadata.type) {
|
||||||
case "ioc":
|
case "ioc":
|
||||||
try {
|
try {
|
||||||
this.bindPlugin(metadata)
|
this.bindPlugin(metadata)
|
||||||
pluginInstance = this.container.getNamed<interfaces.Plugin>(plugin.Plugin, metadata.name)
|
pluginInstance = this.container.getNamed<plugin.Plugin>(plugin.Plugin, metadata.name)
|
||||||
if (!(pluginInstance instanceof interfaces.Plugin)) {
|
if (!(pluginInstance instanceof interfaces.Plugin)) {
|
||||||
console.i18n('ms.plugin.manager.build.not.extends', { source: metadata.source })
|
console.i18n('ms.plugin.manager.build.not.extends', { source: metadata.source })
|
||||||
return
|
return
|
||||||
@ -235,13 +243,13 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
default:
|
default:
|
||||||
throw new Error('§4不支持的插件类型 请检查加载器是否正常启用!')
|
throw new Error('§4不支持的插件类型 请检查加载器是否正常启用!')
|
||||||
}
|
}
|
||||||
this.pluginInstanceMap.set(metadata.name, pluginInstance)
|
pluginInstance && this.pluginInstanceMap.set(metadata.name, pluginInstance)
|
||||||
return pluginInstance
|
return pluginInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
private bindPlugin(metadata: interfaces.PluginMetadata) {
|
private bindPlugin(metadata: interfaces.PluginMetadata) {
|
||||||
try {
|
try {
|
||||||
let pluginInstance = this.container.getNamed<interfaces.Plugin>(plugin.Plugin, metadata.name)
|
let pluginInstance = this.container.getNamed<plugin.Plugin>(plugin.Plugin, metadata.name)
|
||||||
if (pluginInstance.description.source + '' !== metadata.source + '') {
|
if (pluginInstance.description.source + '' !== metadata.source + '') {
|
||||||
console.i18n('ms.plugin.manager.build.duplicate', { exists: pluginInstance.description.source, source: metadata.source })
|
console.i18n('ms.plugin.manager.build.duplicate', { exists: pluginInstance.description.source, source: metadata.source })
|
||||||
}
|
}
|
||||||
@ -251,7 +259,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadConfig(plugin: interfaces.Plugin) {
|
private loadConfig(plugin: plugin.Plugin) {
|
||||||
let configs = getPluginConfigMetadata(plugin)
|
let configs = getPluginConfigMetadata(plugin)
|
||||||
for (let [_, config] of configs) {
|
for (let [_, config] of configs) {
|
||||||
try {
|
try {
|
||||||
@ -276,7 +284,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private saveConfig(plugin: interfaces.Plugin) {
|
private saveConfig(plugin: plugin.Plugin) {
|
||||||
let configs = getPluginConfigMetadata(plugin)
|
let configs = getPluginConfigMetadata(plugin)
|
||||||
for (let [_, config] of configs) {
|
for (let [_, config] of configs) {
|
||||||
try {
|
try {
|
||||||
@ -290,7 +298,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private registryCommand(pluginInstance: interfaces.Plugin) {
|
private registryCommand(pluginInstance: plugin.Plugin) {
|
||||||
let cmds = getPluginCommandMetadata(pluginInstance)
|
let cmds = getPluginCommandMetadata(pluginInstance)
|
||||||
let tabs = getPluginTabCompleterMetadata(pluginInstance)
|
let tabs = getPluginTabCompleterMetadata(pluginInstance)
|
||||||
for (const [_, cmd] of cmds) {
|
for (const [_, cmd] of cmds) {
|
||||||
@ -303,7 +311,7 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private registryListener(pluginInstance: interfaces.Plugin) {
|
private registryListener(pluginInstance: plugin.Plugin) {
|
||||||
let events = getPluginListenerMetadata(pluginInstance)
|
let events = getPluginListenerMetadata(pluginInstance)
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
// ignore space listener
|
// ignore space listener
|
||||||
@ -313,18 +321,18 @@ export class PluginManagerImpl implements plugin.PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unregistryCommand(pluginInstance: interfaces.Plugin) {
|
private unregistryCommand(pluginInstance: plugin.Plugin) {
|
||||||
let cmds = getPluginCommandMetadata(pluginInstance)
|
let cmds = getPluginCommandMetadata(pluginInstance)
|
||||||
cmds.forEach(cmd => {
|
cmds.forEach(cmd => {
|
||||||
this.CommandManager.off(pluginInstance, cmd.name)
|
this.CommandManager.off(pluginInstance, cmd.name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private unregistryListener(pluginInstance: interfaces.Plugin) {
|
private unregistryListener(pluginInstance: plugin.Plugin) {
|
||||||
this.EventManager.disable(pluginInstance)
|
this.EventManager.disable(pluginInstance)
|
||||||
}
|
}
|
||||||
|
|
||||||
private execPluginStage(pluginInstance: interfaces.Plugin, stageName: string) {
|
private execPluginStage(pluginInstance: plugin.Plugin, stageName: string) {
|
||||||
let stages = getPluginStageMetadata(pluginInstance, stageName)
|
let stages = getPluginStageMetadata(pluginInstance, stageName)
|
||||||
for (const stage of stages) {
|
for (const stage of stages) {
|
||||||
if (!this.allowProcess(stage.servers)) { continue }
|
if (!this.allowProcess(stage.servers)) { continue }
|
||||||
|
Loading…
Reference in New Issue
Block a user