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.HaloInterceptor;
import com.github.yoojia.halo.supports.*;
import com.github.yoojia.halo.utils.Classes;
import com.github.yoojia.halo.utils.Scanner;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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 mBridgeChain = new KernelChain();
private final List mKernelModules = Lists.newArrayList();
private final List mUserPlugins = Lists.newArrayList();
private final List mUserListeners = Lists.newArrayList();
private final List mCoreListeners = 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 (CoreLifecycle item : mCoreListeners){
item.onStartup(mContext);
}
}
/**
* 关闭Engine实例,关闭核心模块、插件及监听接口
*/
public void shutdown(){
mLogger.debug("stop...");
for (CoreLifecycle item : mCoreListeners){
item.onShutdown(mContext);
}
}
/**
* 处理请求入口方法
*/
public void service(ServletRequest request, ServletResponse response) {
final HaloRequest haloRequest = new HaloRequest(request);
final HaloResponse haloResponse = new HaloResponse(response);
mLogger.trace("Dispatching request :::: Method={}, Uri={}", haloRequest.method, haloRequest.uri);
try{
mBridgeChain.startService(haloRequest, haloResponse);
}catch (Exception error){
haloResponse.sendError(error);
}
}
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();
tempKernel.add(new Config.Wrapper(-99, new HaloInterceptor(), rootConfig));
tempKernel.add(new Config.Wrapper(0, new HaloAction(), rootConfig));
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);
mBridgeChain.addService(module);
}
mCoreListeners.addAll(mKernelModules);
// 2. User plugins
prepareUserPlugins(classes, mUserPlugins);
mCoreListeners.addAll(mUserPlugins);
// 3. User listeners
prepareUserListeners(classes, mUserListeners);
mCoreListeners.addAll(mUserListeners);
// clear scanner cache
scanner.clean();
}
private void prepareKernelModules(Classes util, List> tempList) {
final List configs = mContext.getRootConfig().getConfigList("appModules");
for (Config c : configs) {
final String className = c.getString("class");
final HaloModule module = util.newClassByName(className);
final int priority = c.getIntValue("priority", 0);
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().getConfigList("appPlugins");
final ArrayList> wrappers = Lists.newArrayList();
for (Config c : configs) {
final String className = c.getString("class");
final HaloPlugin listener = util.newClassByName(className);
final int priority = c.getIntValue("priority", 0);
final Config args = c.getSection("args");
mLogger.trace("Prepare APP plugin, Class={}, Priority={}, Args={}", className, priority, args);
wrappers.add(new Config.Wrapper<>(priority, listener, 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().getConfigList("appListeners");
final ArrayList> wrappers = Lists.newArrayList();
for (Config c : configs) {
final String className = c.getString("class");
final HaloListener listener = util.newClassByName(className);
final int priority = c.getIntValue("priority", 0);
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);
}
}
}