[Move] Core, Event-API(Event), Framework-API, Template-API(Template) 更改模块名以规范命名;

[Move] :Event-API 更改模块名(原 'Event');
[Move] :Template-API 更改模块名(原 'Template');
[Change] Project/pom.xml 适配更改;
[Change] :Core, :Framework-API 适配更改;
This commit is contained in:
2021-02-13 13:09:16 +08:00
parent 612956b594
commit 711c80175e
19 changed files with 12 additions and 11 deletions

View File

@ -0,0 +1,40 @@
# Event 模块 #
Event 模块用于定义 ContentGrabbingJi 所使用事件系统的规范。
通过定义事件系统的规范接口,可增加项目模块配置的灵活性。
虽说如此,但 Event 模块并未计划允许用户任意更换,仅允许于开发阶段更换。
## 组件 ##
### EventExecutor 事件执行器
事件执行器用于接收任意事件,并将事件交给可处理该事件的对象方法。
根据实现不同,事件执行器可能是同步的,也可能是异步的,需检查 `isAsync` 方法返回值以了解相关信息。
### EventObject 事件对象
当某一对象实现 `EventObject` 时,对象即为事件对象,
事件对象可交由事件执行器分发到处理方法中。
### HandlerRegistry 事件处理注册器
用于注册并存储所有 EventHandler 内符合条件的处理方法。
在 EventExecutor 需要时将会请求可处理事件的所有处理方法。
### EventHandler 事件处理器
当某一对象实现 `EventHandler` 时,则表明该对象包含用于处理指定事件的处理方法。
HandlerRegistry 将会扫描内部方法,并将符合要求的方法注册为处理方法。
### EventObject 事件对象
事件对象接口,实现了该接口的对象将视为一种事件对象。
事件对象可通过 EventExecutor 投递到任何可处理该事件的处理方法进行处理。
### AbstractEventObject 抽象事件对象
实现了 EventObject 中 `getEventId` 方法的抽象对象。
### Cancelable 可取消事件
当事件实现了该接口时,代表事件可以被取消。
当事件被取消后EventExecutor 将会终止处理该事件,同时事件将通知所有已注册的 Observer。
### SupportedCancel 支持取消接口
当 EventExecutor 实现该接口时,表明 EventExecutor 拥有在事件取消时终止事件的能力,
需要注意的是,即使 EventExecutor 未实现该接口,也不一定代表 EventExecutor 不支持终止事件的处理。
## 相关实现 ##
目前已有默认的实现存在于 Core 模块中,目前暂不需要开发其他实现。

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (C) 2021 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.
~
~ 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/>.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ContentGrabbingJi</artifactId>
<groupId>net.lamgc</groupId>
<version>3.0.0-alpha-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ContentGrabbingJi-Event-api</artifactId>
</project>

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.util.UUID;
/**
* 抽象事件对象.
* <p> 已完成对 {@link EventObject#getEventId()} 的实现.
* @author LamGC
*/
public abstract class AbstractEventObject implements EventObject {
private final UUID eventId = UUID.randomUUID();
@Override
public UUID getEventId() {
return eventId;
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.util.Observer;
/**
* 可取消接口.
* <p> 实现了该接口的事件可对其处理进行取消.
* <p> 注意: 取消操作是不可逆的!
* @author LamGC
*/
public interface Cancelable {
/**
* 取消该事件.
* <p> 该操作不可逆.
* <p> 调用本方法后, 将会触发所有已通过 {@link #registerCancelObserver(Observer)} 注册的 {@link Observer} 事件取消的状态变更.
* @see #registerCancelObserver(Observer)
*/
void cancel();
/**
* 检查事件是否已被取消.
* <p> 注意: 本方法不同于 {@link Thread#interrupted()} 方法, 即使调用本方法, 也不会清除取消状态(取消操作是不可逆的).
* @return 如果事件已被取消, 返回 true.
*/
boolean canceled();
/**
* 注册事件取消监听器.
* <p> 注意: 如果发生取消事件, 无论 {@link java.util.Observable} 是否为事件对象本身, 参数 {@code arg} 都必须传递事件对象自身!
* @param cancelObserver 观察者对象.
* @throws UnsupportedOperationException 当该可取消对象不支持 {@link java.util.Observable} 时抛出,
* 既然不支持观察取消事件, 那么 {@link #observableCancel()} 应当返回 {@code false}, 否则该方法不允许抛出该异常.
*/
default void registerCancelObserver(Observer cancelObserver) throws UnsupportedOperationException {
throw new UnsupportedOperationException("This operation is not supported by this event.");
}
/**
* 是否可观察取消事件.
* <p> 如果本方法返回 {@code true},
* 那么 {@link #registerCancelObserver(Observer)} 不允许抛出 {@link UnsupportedOperationException} 异常.
* @return 如果可以, 返回 true.
*/
default boolean observableCancel() {
return false;
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
/**
* 事件执行器.
* @author LamGC
*/
public interface EventExecutor {
/**
* 执行事件.
* @param event 事件对象.
*/
void execute(EventObject event);
/**
* 是否为异步事件执行器.
* @return 如果为异步事件执行器, 返回 {@code true}, 如果为同步事件执行器, 返回 {@code false}.
*/
boolean isAsync();
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 事件处理器注解.
* <p> 标记了该注解的方法, 如符合处理方法条件, 则会被 {@link HandlerRegistry} 注册为事件处理方法.
* @author LamGC
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventHandler {
/**
* 是否接受事件对象的子类.
* <p> 当该选项为 {@code true} 时, 子类事件也会传递到该方法进行处理.
* 例如事件 Parent, 和它的子类 Child, 处理方法: {@code handler(Parent event)};
* 如果该选项为 {@code true}, 那么 Child 也会传递到该方法进行处理, 反之, 如果该选项为 {@code false},
* 那么该方法只会接收 Parent 事件, 而不会接收它的子类 Child.
* <p> 默认值: {@code false}
* @return 返回该方法是否支持继承性.
*/
boolean inheritable() default false;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.util.UUID;
/**
* 事件对象.
* @author LamGC
*/
public interface EventObject {
/**
* 获取事件 UUID.
* <p> 需保证 UUID 对应了唯一的事件对象, 即使内容重复.
* @return 返回事件Id.
*/
UUID getEventId();
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 事件处理工具类.
* @author LamGC
*/
public final class EventUtils {
private EventUtils() {}
/**
* 检查 {@link EventExecutor} 是否支持取消事件.
* @param executor 事件执行器.
* @return 如果支持, 返回 {@code true}
*/
public static boolean isSupportedCancel(EventExecutor executor) {
return executor instanceof SupportedCancel;
}
/**
* 检查方法是否符合事件处理方法条件.
* @param method 待检查的方法.
* @return 如果符合, 返回 true.
*/
public static boolean checkEventHandlerMethod(Method method) {
int modifiers = method.getModifiers();
// 新版事件系统将不再允许静态方法作为事件处理方法, 以降低管理难度.
if (!Modifier.isPublic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isStatic(modifiers)) {
return false;
}
if (!method.isAnnotationPresent(EventHandler.class) || method.getParameterCount() != 1) {
return false;
}
Class<?> param = method.getParameterTypes()[0];
if (!EventObject.class.isAssignableFrom(param)) {
return false;
}
return method.getReturnType().equals(Void.TYPE);
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 事件处理注册器.
* <p> 实现了该接口的类将允许注册事件处理方法.
* @author LamGC
*/
public interface HandlerRegistry {
/**
* 注册对象中的事件处理方法.
* @param handlerObject 包含事件处理方法的对象.\
* @return 返回已成功添加的方法数.
*/
int registerHandler(Object handlerObject);
/**
* 获取能处理指定事件的所有方法.
* @param event 待匹配的事件对象.
* @return 返回一个集合, 集合存储了可处理该事件的所有方法和它所属类的对象.
*/
Map<Method, Object> getMatchedHandlerMethod(EventObject event);
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import java.util.NoSuchElementException;
import java.util.UUID;
/**
* 支持取消接口.
* <p> 实现了该接口的 {@link EventExecutor} 可对已投递执行的事件进行取消, 以阻止事件被执行.
* @author LamGC
*/
public interface SupportedCancel {
/**
* 通过 EventId 取消事件的处理.
* @param eventId 事件Id.
* @return 如果成功, 返回 true, 如果事件已执行完成, 返回 false.
* @throws UnsupportedOperationException 当事件未实现 {@link Cancelable} 接口时抛出.
* @throws NoSuchElementException 当 EventId 所属事件在 {@link SupportedCancel} 中无法找到时抛出.
*/
boolean cancelEvent(UUID eventId) throws UnsupportedOperationException, NoSuchElementException;
/**
* 通过 Event 对象取消事件的处理.
* @param event 事件对象.
* @return 如果成功, 返回 true, 如果事件已执行完成, 返回 false.
* @throws UnsupportedOperationException 当事件未实现 {@link Cancelable} 接口时抛出.
* @throws NoSuchElementException 当事件在 {@link SupportedCancel} 中无法找到时抛出.
*/
boolean cancelEvent(EventObject event) throws UnsupportedOperationException, NoSuchElementException;
/**
* 对可取消对象执行取消处理操作.
* @param cancelableEvent 可取消对象事件.
* @return 如果成功, 返回 true, 如果事件已执行完成, 返回 false.
* @throws NoSuchElementException 当事件在 {@link SupportedCancel} 中无法找到时抛出.
* @throws IllegalArgumentException 当 Cancelable 对象未实现 {@link EventObject} (即不是一个事件对象) 时抛出.
*/
boolean cancelEvent(Cancelable cancelableEvent) throws NoSuchElementException, IllegalArgumentException;
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2021 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.
*
* 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.event;
import net.lamgc.cgj.bot.event.handler.IllegalHandler;
import net.lamgc.cgj.bot.event.handler.StandardHandler;
import net.lamgc.cgj.bot.event.object.TestEvent;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.NoSuchElementException;
import java.util.UUID;
/**
* @see EventUtils
*/
public class EventUtilsTest {
@Test
public void supportedCancelCheckTest() {
class NonSupportedCancelClass implements EventExecutor {
@Override
public void execute(EventObject event) {
}
@Override
public boolean isAsync() {
return false;
}
}
class SupportedCancelClass implements SupportedCancel, EventExecutor {
@Override
public boolean cancelEvent(UUID eventId) throws UnsupportedOperationException, NoSuchElementException {
return false;
}
@Override
public boolean cancelEvent(EventObject event) throws UnsupportedOperationException, NoSuchElementException {
return false;
}
@Override
public boolean cancelEvent(Cancelable cancelableEvent) throws NoSuchElementException {
return false;
}
@Override
public void execute(EventObject event) {
}
@Override
public boolean isAsync() {
return false;
}
}
Assert.assertTrue(EventUtils.isSupportedCancel(new SupportedCancelClass()));
Assert.assertFalse(EventUtils.isSupportedCancel(new NonSupportedCancelClass()));
}
@Test
public void standardHandlerMethodCheckTest() throws NoSuchMethodException {
Method targetMethod = StandardHandler.class.getMethod("standardHandle", TestEvent.class);
Assert.assertTrue(EventUtils.checkEventHandlerMethod(targetMethod));
}
@Test
public void invalidHandlerMethodCheckTest() {
for (Method method : IllegalHandler.class.getDeclaredMethods()) {
Assert.assertFalse(EventUtils.checkEventHandlerMethod(method));
}
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2021 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.
*
* 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.event.handler;
import net.lamgc.cgj.bot.event.EventHandler;
import net.lamgc.cgj.bot.event.object.TestEvent;
public abstract class IllegalHandler {
@EventHandler
public void nonArgumentHandleMethod() {
}
@EventHandler
public abstract void abstractHandleMethod(TestEvent event);
@EventHandler
public static void staticHandleMethod(TestEvent event) {
}
@EventHandler
private void privateHandleMethod(TestEvent event) {
}
public void nonAnnotationHandle() {
}
@EventHandler
public void multiArgumentsHandleMethod(TestEvent event, Object object) {
}
@EventHandler
public void invalidArgumentMethod(Object object) {
}
@EventHandler
public Object invalidReturnTypeMethod(TestEvent event) {
return null;
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (C) 2021 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.
*
* 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.event.handler;
import net.lamgc.cgj.bot.event.EventHandler;
import net.lamgc.cgj.bot.event.object.TestEvent;
public class StandardHandler {
@EventHandler
public void standardHandle(TestEvent event) {
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2021 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.
*
* 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.event.object;
import net.lamgc.cgj.bot.event.AbstractEventObject;
public class TestEvent extends AbstractEventObject {
private final String content;
public TestEvent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}