com.github.yoojia.halo.HaloEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of halo-core Show documentation
Show all versions of halo-core Show documentation
A FAST && THIN && HIGH SCALABLE Java web framework
package com.github.yoojia.halo;
import com.github.yoojia.halo.actions.HaloAction;
import com.github.yoojia.halo.interceptors.HaloAfterInterceptor;
import com.github.yoojia.halo.interceptors.HaloBeforeInterceptor;
import com.github.yoojia.halo.supports.*;
import com.github.yoojia.halo.utils.Classes;
import com.github.yoojia.halo.utils.Scanner;
import com.github.yoojia.halo.utils.SystemTime;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* @author YOOJIA.CHEN ([email protected])
*/
public final class HaloEngine {
private final Logger mLogger = LoggerFactory.getLogger(HaloEngine.class);
private final static ThreadLocal INSTANCE_FLAG = new ThreadLocal<>();
private Context mContext;
private final KernelChain mKernelChain = new KernelChain();
private final List mKernelModules = Lists.newArrayList();
private final List mUserPlugins = Lists.newArrayList();
private final List mUserListeners = Lists.newArrayList();
private final List<$$> mCoreTriggers = Lists.newArrayList();
private final Ordering mPriorityOrdering = Ordering.from(new Comparator() {
@Override
public int compare(Config.Wrapper w1, Config.Wrapper w2) {
return w1.priority > w2.priority ? 1 : -1;
}
});
/**
* 根据指定WebRoot路径来初始化 Engine 运行环境
*/
public void init(String webRoot){
mLogger.debug("[email protected]: {}", Thread.currentThread().getId());
mLogger.debug("Web root: {}", webRoot);
if(INSTANCE_FLAG.get() != null){
mLogger.warn("\n\n==== ANOTHER HALOEngine INSTANCE IS RUNNING ===\n");
}
INSTANCE_FLAG.set(true);
final Scanner scanner = new Scanner();
mContext = new Context(scanner, webRoot);
engineInit();
}
/**
* 启动Engine,加载核心模块、插件及监听接口
*/
public void startup(){
mLogger.debug("start...");
for ($$ item : mCoreTriggers){
item.onStartup(mContext);
}
}
/**
* 关闭Engine实例,关闭核心模块、插件及监听接口
*/
public void shutdown(){
mLogger.debug("stop...");
for ($$ item : mCoreTriggers){
item.onShutdown(mContext);
}
}
/**
* 处理请求入口方法
*/
public void route(HttpServletRequest request, HttpServletResponse response) {
final HaloRequest haloRequest = new HaloRequest(request);
final HaloResponse haloResponse = new HaloResponse(response);
mLogger.trace("### Request START: Method={}, Uri={}", haloRequest.method, haloRequest.uri);
final long requestTime = System.nanoTime();
try{
mKernelChain.dispatch(haloRequest, haloResponse);
}catch (Exception error){
haloResponse.sendError(error);
}finally {
mLogger.trace("### Request END: Code={}, Uri={}", haloResponse.getStatusCode(), haloRequest.uri);
SystemTime.log(requestTime, "HALOEngine.route()");
}
}
private void engineInit(){
final Scanner scanner = mContext.getClassScanner();
scanner.start();
final Classes classes = new Classes();
// 1. Kernel modules
final Config rootConfig = mContext.getRootConfig();
final List> tempKernel = Lists.newArrayList();
final HaloBeforeInterceptor beforeInterceptor = new HaloBeforeInterceptor();
tempKernel.add(new Config.Wrapper(beforeInterceptor.getPriority(),
beforeInterceptor, rootConfig.getSection("beforeInterceptor")));
final HaloAfterInterceptor afterInterceptor = new HaloAfterInterceptor();
tempKernel.add(new Config.Wrapper(afterInterceptor.getPriority(),
afterInterceptor, rootConfig.getSection("afterInterceptor")));
final HaloAction action = new HaloAction();
tempKernel.add(new Config.Wrapper(action.getPriority(), action,
rootConfig.getSection("httpAction")));
prepareKernelModules(classes, tempKernel);
for(Config.Wrapper c : mPriorityOrdering.sortedCopy(tempKernel)) {
final HaloModule module = c.target;
module.init(mContext, c.args == null ? rootConfig : c.args);
mKernelModules.add(module);
mKernelChain.addService(module);
}
mCoreTriggers.addAll(mKernelModules);
// 2. User plugins
prepareUserPlugins(classes, mUserPlugins);
mCoreTriggers.addAll(mUserPlugins);
// 3. User listeners
prepareUserListeners(classes, mUserListeners);
mCoreTriggers.addAll(mUserListeners);
// clear scanner cache
scanner.clean();
}
private void prepareKernelModules(Classes util, List> tempList) {
final List configs = mContext.getRootConfig().getSections("appModules");
for (Config c : configs) {
final String className = c.getValue("class", null);
final HaloModule module = util.newClassByName(className);
final int priority = c.getValue("priority", module.getPriority());
final Config args = c.getSection("args");
mLogger.trace("Prepare APP module, Class={}, Priority={}, Args={}", className, priority, args);
tempList.add(new Config.Wrapper<>(priority, module, args));
}
}
private void prepareUserPlugins(Classes util, List plugins) {
final List configs = mContext.getRootConfig().getSections("appPlugins");
final ArrayList> wrappers = Lists.newArrayList();
for (Config c : configs) {
final String className = c.getValue("class", null);
final HaloPlugin plugin = util.newClassByName(className);
final int priority = c.getValue("priority", plugin.getPriority());
final Config args = c.getSection("args");
mLogger.trace("Prepare APP plugin, Class={}, Priority={}, Args={}", className, priority, args);
wrappers.add(new Config.Wrapper<>(priority, plugin, args));
}
// 排序Plugin数组,优先级大的排在后面
for(Config.Wrapper w : mPriorityOrdering.sortedCopy(wrappers)){
w.target.init(mContext, w.args);
plugins.add(w.target);
}
}
private void prepareUserListeners(Classes util, List listeners){
final List configs = mContext.getRootConfig().getSections("appListeners");
final ArrayList> wrappers = Lists.newArrayList();
for (Config c : configs) {
final String className = c.getValue("class", null);
final HaloListener listener = util.newClassByName(className);
final int priority = c.getValue("priority", listener.getPriority());
mLogger.trace("Prepare APP listener, Class={}, Priority={}", className, priority);
wrappers.add(new Config.Wrapper<>(priority, listener, null));
}
// 排序Listener数组,优先级大的排在后面
for(Config.Wrapper w : mPriorityOrdering.sortedCopy(wrappers)){
listeners.add(w.target);
}
}
}