mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-07-01 21:07:25 +00:00
[Change] Framework-API, Core 将 PluginManager 相关迁移至 Core 模块;
[Change] * 从 Framework-API 迁移至 Core 模块;
This commit is contained in:
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework;
|
||||
|
||||
import net.lamgc.cgj.bot.framework.message.BotCodeDescriptor;
|
||||
import org.pf4j.PluginDependency;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 默认框架描述对象.
|
||||
* @author LamGC
|
||||
*/
|
||||
class DefaultFrameworkDescriptor implements FrameworkDescriptor {
|
||||
|
||||
private String id;
|
||||
private String description;
|
||||
private String version;
|
||||
private String requiresVersion;
|
||||
private String provider;
|
||||
private String license;
|
||||
private String frameworkClass;
|
||||
private final List<PluginDependency> dependencies = new ArrayList<>();
|
||||
|
||||
private Platform platform;
|
||||
private BotCodeDescriptor botCode;
|
||||
private List<Author> authors;
|
||||
|
||||
@Override
|
||||
public String getPluginId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginClass() {
|
||||
return frameworkClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequires() {
|
||||
return requiresVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PluginDependency> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Platform getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BotCodeDescriptor getBotCodeDescriptor() {
|
||||
return botCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Author> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework;
|
||||
|
||||
import org.pf4j.Plugin;
|
||||
import org.pf4j.PluginFactory;
|
||||
import org.pf4j.PluginWrapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* 经过调整的, 针对 Framework 的实例工厂类.
|
||||
* @author LamGC
|
||||
*/
|
||||
final class FrameworkFactory implements PluginFactory {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(FrameworkFactory.class);
|
||||
|
||||
private final File dataRootFolder;
|
||||
|
||||
public FrameworkFactory(File dataRootFolder) {
|
||||
this.dataRootFolder = dataRootFolder;
|
||||
if (!this.dataRootFolder.exists() && !this.dataRootFolder.mkdirs()) {
|
||||
log.warn("框架数据目录创建异常, 可能会导致后续框架存取数据失败!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin create(PluginWrapper pluginWrapper) {
|
||||
String pluginClassName = pluginWrapper.getDescriptor().getPluginClass();
|
||||
log.debug("Create instance for framework '{}'", pluginClassName);
|
||||
|
||||
Class<?> pluginClass;
|
||||
try {
|
||||
pluginClass = pluginWrapper.getPluginClassLoader().loadClass(pluginClassName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果成功获取类, 就需要对其检查, 以确保类符合框架主类的要求.
|
||||
int modifiers = pluginClass.getModifiers();
|
||||
if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)
|
||||
|| (!Framework.class.isAssignableFrom(pluginClass))) {
|
||||
log.error("The framework class '{}' is not valid", pluginClassName);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// <init>(PluginWrapper, DataFolder)
|
||||
Constructor<?> constructor = pluginClass.getConstructor(PluginWrapper.class, File.class);
|
||||
return (Plugin) constructor.newInstance(pluginWrapper,
|
||||
new File(dataRootFolder, pluginWrapper.getPluginId()));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework;
|
||||
|
||||
import org.pf4j.*;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 框架管理器.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class FrameworkManager extends JarPluginManager {
|
||||
|
||||
public FrameworkManager(String systemVersion, File frameworksDirectory) {
|
||||
super(frameworksDirectory.toPath());
|
||||
setSystemVersion(systemVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PluginDescriptorFinder createPluginDescriptorFinder() {
|
||||
return new JsonFrameworkDescriptorFinder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PluginRepository createPluginRepository() {
|
||||
return new CompoundPluginRepository()
|
||||
.add(new DevelopmentPluginRepository(getPluginsRoot()), this::isDevelopment)
|
||||
.add(new JarPluginRepository(getPluginsRoot()), this::isNotDevelopment)
|
||||
.add(new DefaultPluginRepository(getPluginsRoot()), this::isNotDevelopment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PluginFactory createPluginFactory() {
|
||||
return new FrameworkFactory(getPluginsRoot().getParent().resolve("frameworkData").toFile());
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.lamgc.cgj.bot.framework.message.BotCodeDescriptor;
|
||||
import net.lamgc.cgj.bot.framework.util.AuthorJsonSerializer;
|
||||
import net.lamgc.cgj.bot.framework.util.BotCodeDescriptorJsonSerializer;
|
||||
import net.lamgc.cgj.bot.framework.util.PlatformJsonSerializer;
|
||||
import net.lamgc.cgj.bot.framework.util.PluginDependencyJsonSerializer;
|
||||
import org.pf4j.PluginDependency;
|
||||
import org.pf4j.PluginDescriptor;
|
||||
import org.pf4j.PluginDescriptorFinder;
|
||||
import org.pf4j.PluginRuntimeException;
|
||||
import org.pf4j.util.FileUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Json格式的框架描述文件查找器.
|
||||
* @author LamGC
|
||||
*/
|
||||
class JsonFrameworkDescriptorFinder implements PluginDescriptorFinder {
|
||||
|
||||
private final static String DESCRIPTOR_FILE_NAME = "framework.json";
|
||||
private final Gson gson;
|
||||
|
||||
public JsonFrameworkDescriptorFinder() {
|
||||
this(new Gson());
|
||||
}
|
||||
|
||||
public JsonFrameworkDescriptorFinder(Gson gson) {
|
||||
this.gson = gson.newBuilder()
|
||||
.serializeNulls()
|
||||
.registerTypeAdapter(Author.class, new AuthorJsonSerializer())
|
||||
.registerTypeAdapter(BotCodeDescriptor.class, new BotCodeDescriptorJsonSerializer())
|
||||
.registerTypeAdapter(Platform.class, new PlatformJsonSerializer())
|
||||
.registerTypeAdapter(PluginDependency.class, new PluginDependencyJsonSerializer())
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(Path frameworkPath) {
|
||||
return Files.exists(frameworkPath) && (Files.isDirectory(frameworkPath) || FileUtils.isJarFile(frameworkPath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginDescriptor find(Path frameworkPath) {
|
||||
JsonObject descriptorObject = loadFrameworkDescriptorObject(frameworkPath);
|
||||
return createFrameworkDescriptor(descriptorObject);
|
||||
}
|
||||
|
||||
private Path getFrameworkDescriptorPath(Path frameworkPath) {
|
||||
if (Files.isDirectory(frameworkPath)) {
|
||||
return frameworkPath.resolve(Paths.get(DESCRIPTOR_FILE_NAME));
|
||||
} else {
|
||||
try {
|
||||
return FileUtils.getPath(frameworkPath, DESCRIPTOR_FILE_NAME);
|
||||
} catch (IOException e) {
|
||||
throw new PluginRuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject loadFrameworkDescriptorObject(Path frameworkPath) {
|
||||
Path descriptorPath = getFrameworkDescriptorPath(frameworkPath);
|
||||
if (frameworkPath == null) {
|
||||
throw new PluginRuntimeException("Cannot find the json path");
|
||||
}
|
||||
|
||||
JsonObject descriptorObject;
|
||||
try {
|
||||
if (Files.notExists(descriptorPath)) {
|
||||
throw new PluginRuntimeException("Cannot find '{}' path", descriptorPath);
|
||||
}
|
||||
try (InputStream input = Files.newInputStream(descriptorPath)) {
|
||||
descriptorObject = gson.fromJson(
|
||||
new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)), JsonObject.class);
|
||||
} catch (IOException e) {
|
||||
throw new PluginRuntimeException("Exception loading descriptor", e);
|
||||
}
|
||||
} finally {
|
||||
FileUtils.closePath(descriptorPath);
|
||||
}
|
||||
return descriptorObject;
|
||||
}
|
||||
|
||||
private FrameworkDescriptor createFrameworkDescriptor(JsonObject descriptorObject) {
|
||||
return gson.fromJson(descriptorObject, DefaultFrameworkDescriptor.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework.util;
|
||||
|
||||
import com.google.gson.*;
|
||||
import net.lamgc.cgj.bot.framework.Author;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* {@link Author} Json 序列化工具.
|
||||
* @see Author
|
||||
* @author LamGC
|
||||
*/
|
||||
public class AuthorJsonSerializer implements JsonSerializer<Author>, JsonDeserializer<Author> {
|
||||
|
||||
private final static String FIELD_NAME = "name";
|
||||
private final static String FIELD_URL = "url";
|
||||
private final static String FIELD_EMAIL = "email";
|
||||
|
||||
@Override
|
||||
public Author deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
if (!json.isJsonObject()) {
|
||||
throw new JsonParseException("Not a JsonObject");
|
||||
}
|
||||
|
||||
JsonObject authorObject = json.getAsJsonObject();
|
||||
if (!authorObject.has(FIELD_NAME) || !authorObject.get(FIELD_NAME).isJsonPrimitive()) {
|
||||
throw new JsonParseException("A required field is missing or the type is incorrect: " + FIELD_NAME);
|
||||
}
|
||||
|
||||
String name = authorObject.get(FIELD_NAME).getAsString();
|
||||
String url = authorObject.has(FIELD_URL) && authorObject.get(FIELD_URL).isJsonPrimitive() ?
|
||||
authorObject.get(FIELD_URL).getAsString() : null;
|
||||
String email = authorObject.has(FIELD_EMAIL) && authorObject.get(FIELD_EMAIL).isJsonPrimitive() ?
|
||||
authorObject.get(FIELD_EMAIL).getAsString() : null;
|
||||
|
||||
return new Author(name, url, email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Author src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject result = new JsonObject();
|
||||
result.addProperty(FIELD_NAME, src.getName());
|
||||
result.addProperty(FIELD_URL, src.getUrl());
|
||||
result.addProperty(FIELD_EMAIL, src.getEmail());
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework.util;
|
||||
|
||||
import com.google.gson.*;
|
||||
import net.lamgc.cgj.bot.framework.message.BotCodeDescriptor;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* BotCode 描述对象序列化工具.
|
||||
* @see BotCodeDescriptor
|
||||
* @author LamGC
|
||||
*/
|
||||
public class BotCodeDescriptorJsonSerializer
|
||||
implements JsonSerializer<BotCodeDescriptor>, JsonDeserializer<BotCodeDescriptor> {
|
||||
|
||||
private final static String FIELD_PATTERNS = "patterns";
|
||||
|
||||
@Override
|
||||
public BotCodeDescriptor deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
if (!json.isJsonObject()) {
|
||||
throw new JsonParseException("Not a JsonObject");
|
||||
}
|
||||
|
||||
JsonObject descriptorObject = json.getAsJsonObject();
|
||||
List<String> patternStrings = new ArrayList<>();
|
||||
if (descriptorObject.has(FIELD_PATTERNS) && descriptorObject.get(FIELD_PATTERNS).isJsonArray()) {
|
||||
for (JsonElement jsonElement : descriptorObject.getAsJsonArray(FIELD_PATTERNS)) {
|
||||
if (!jsonElement.isJsonPrimitive()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonPrimitive primitive = jsonElement.getAsJsonPrimitive();
|
||||
if (!primitive.isString()) {
|
||||
continue;
|
||||
}
|
||||
patternStrings.add(primitive.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
return new BotCodeDescriptor(patternStrings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(BotCodeDescriptor src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject result = new JsonObject();
|
||||
|
||||
JsonArray patterns = new JsonArray();
|
||||
for (Pattern pattern : src.getPatterns()) {
|
||||
patterns.add(pattern.pattern());
|
||||
}
|
||||
result.add(FIELD_PATTERNS, patterns);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework.util;
|
||||
|
||||
import com.google.gson.*;
|
||||
import net.lamgc.cgj.bot.framework.Platform;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* {@link Platform} 序列化工具.
|
||||
* @see Platform
|
||||
* @author LamGC
|
||||
*/
|
||||
public final class PlatformJsonSerializer implements JsonSerializer<Platform>, JsonDeserializer<Platform> {
|
||||
|
||||
private final static String FIELD_NAME = "name";
|
||||
private final static String FIELD_IDENTIFY = "identify";
|
||||
|
||||
|
||||
@Override
|
||||
public Platform deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
if (!json.isJsonObject()) {
|
||||
throw new JsonParseException("Not a JsonObject");
|
||||
}
|
||||
|
||||
JsonObject descriptorObject = json.getAsJsonObject();
|
||||
if (!descriptorObject.has(FIELD_NAME) || !descriptorObject.has(FIELD_IDENTIFY)) {
|
||||
throw new JsonParseException("A required field is missing");
|
||||
}
|
||||
return new Platform(descriptorObject.get(FIELD_NAME).getAsString(),
|
||||
descriptorObject.get(FIELD_IDENTIFY).getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Platform src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject result = new JsonObject();
|
||||
result.addProperty(FIELD_NAME, src.getPlatformName());
|
||||
result.addProperty(FIELD_IDENTIFY, src.getPlatformIdentify());
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework.util;
|
||||
|
||||
import com.google.gson.*;
|
||||
import org.pf4j.PluginDependency;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* PluginDependency Json 序列化/反序列化 工具.
|
||||
* @see PluginDependency
|
||||
* @author LamGC
|
||||
*/
|
||||
public class PluginDependencyJsonSerializer implements JsonSerializer<PluginDependency>, JsonDeserializer<PluginDependency> {
|
||||
private final static String PLUGIN_VERSION_SUPPORT_ALL = "*";
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(PluginDependency src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
StringBuilder builder = new StringBuilder(src.getPluginId());
|
||||
String pluginVersionSupport = src.getPluginVersionSupport();
|
||||
if (src.isOptional()) {
|
||||
builder.append('?');
|
||||
}
|
||||
if (src.getPluginVersionSupport() != null || !PLUGIN_VERSION_SUPPORT_ALL.equals(pluginVersionSupport)) {
|
||||
builder.append('@').append(pluginVersionSupport);
|
||||
}
|
||||
return new JsonPrimitive(builder.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginDependency deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
if (!json.isJsonPrimitive()) {
|
||||
throw new JsonParseException("Only JsonPrimitive types are supported for conversion");
|
||||
}
|
||||
|
||||
JsonPrimitive primitive = json.getAsJsonPrimitive();
|
||||
if (!primitive.isString()) {
|
||||
throw new JsonParseException("Only String is supported");
|
||||
}
|
||||
|
||||
return new PluginDependency(primitive.getAsString());
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.framework;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import net.lamgc.cgj.bot.framework.message.BotCodeDescriptor;
|
||||
import net.lamgc.cgj.bot.framework.util.AuthorJsonSerializer;
|
||||
import net.lamgc.cgj.bot.framework.util.BotCodeDescriptorJsonSerializer;
|
||||
import net.lamgc.cgj.bot.framework.util.PlatformJsonSerializer;
|
||||
import net.lamgc.cgj.bot.framework.util.PluginDependencyJsonSerializer;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.pf4j.PluginDependency;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class JsonFrameworkDescriptorSerializerTest {
|
||||
|
||||
@Test
|
||||
public void deserializerTest() throws IOException {
|
||||
InputStream resource = getClass().getClassLoader().getResourceAsStream("test-framework.json");
|
||||
if (resource == null) {
|
||||
Assert.fail("未找到测试用资源: test-framework.json");
|
||||
}
|
||||
FrameworkDescriptor descriptor;
|
||||
try (Reader resourceReader = new BufferedReader(new InputStreamReader(resource, StandardCharsets.UTF_8))) {
|
||||
descriptor = getGson().fromJson(resourceReader, DefaultFrameworkDescriptor.class);
|
||||
}
|
||||
|
||||
Assert.assertEquals("cgj-mirai", descriptor.getPluginId());
|
||||
Assert.assertEquals("test", descriptor.getPluginDescription());
|
||||
Assert.assertEquals("3.0.0-alpha", descriptor.getVersion());
|
||||
Assert.assertEquals("=>3.0.0", descriptor.getRequires());
|
||||
Assert.assertEquals("Github@LamGC, Github@mamoe", descriptor.getProvider());
|
||||
Assert.assertEquals("AGPL-3.0", descriptor.getLicense());
|
||||
Assert.assertEquals("com.example.FrameworkMain", descriptor.getPluginClass());
|
||||
|
||||
List<PluginDependency> expectedDependency = new ArrayList<>();
|
||||
expectedDependency.add(new PluginDependency("xxx@1.0.0"));
|
||||
expectedDependency.add(new PluginDependency("xxx optional add->?@1.0.0"));
|
||||
|
||||
Assert.assertEquals(expectedDependency, descriptor.getDependencies());
|
||||
|
||||
Assert.assertEquals("Tencent QQ", descriptor.getPlatform().getPlatformName());
|
||||
Assert.assertEquals("qq", descriptor.getPlatform().getPlatformIdentify());
|
||||
|
||||
List<Author> expectedAuthors = new ArrayList<>();
|
||||
expectedAuthors.add(new Author("LamGC", "https://github.com/LamGC", "lam827@lamgc.net"));
|
||||
|
||||
Assert.assertEquals(expectedAuthors, descriptor.getAuthors());
|
||||
|
||||
List<String> expectedBotCodePatterns = new ArrayList<>();
|
||||
expectedBotCodePatterns.add("(?:\\[mirai:([^:]+)\\])");
|
||||
expectedBotCodePatterns.add("(?:\\[mirai:([^\\]]*)?:(.*?)?\\])");
|
||||
expectedBotCodePatterns.add("(?:\\[mirai:([^\\]]*)?(:(.*?))*?\\])");
|
||||
|
||||
for (Pattern pattern : descriptor.getBotCodeDescriptor().getPatterns()) {
|
||||
if (!expectedBotCodePatterns.contains(pattern.pattern())) {
|
||||
Assert.fail("存在不符的表达式: " + pattern.pattern());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Gson getGson() {
|
||||
return new GsonBuilder()
|
||||
.serializeNulls()
|
||||
.registerTypeAdapter(Author.class, new AuthorJsonSerializer())
|
||||
.registerTypeAdapter(BotCodeDescriptor.class, new BotCodeDescriptorJsonSerializer())
|
||||
.registerTypeAdapter(Platform.class, new PlatformJsonSerializer())
|
||||
.registerTypeAdapter(PluginDependency.class, new PluginDependencyJsonSerializer())
|
||||
.create();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
{
|
||||
"id": "cgj-mirai",
|
||||
"description": "test",
|
||||
"version": "3.0.0-alpha",
|
||||
"requiresVersion": "=>3.0.0",
|
||||
"provider": "Github@LamGC, Github@mamoe",
|
||||
"license": "AGPL-3.0",
|
||||
"frameworkClass": "com.example.FrameworkMain",
|
||||
"dependencies": [
|
||||
"xxx@1.0.0",
|
||||
"xxx optional add->?@1.0.0"
|
||||
],
|
||||
|
||||
"platform": {
|
||||
"name": "Tencent QQ",
|
||||
"identify": "qq"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "LamGC",
|
||||
"url": "https://github.com/LamGC",
|
||||
"email": "lam827@lamgc.net"
|
||||
}
|
||||
],
|
||||
"botCode": {
|
||||
"patterns": [
|
||||
"(?:\\[mirai:([^:]+)\\])",
|
||||
"(?:\\[mirai:([^\\]]*)?:(.*?)?\\])",
|
||||
"(?:\\[mirai:([^\\]]*)?(:(.*?))*?\\])"
|
||||
]
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user