All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.yoojia.halo.HaloEngine Maven / Gradle / Ivy

There is a newer version: 1.1.2
Show newest version
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);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy