/**
 * Copyright (c) 2015-2017, Michael Yang 杨福海 (fuhai999@gmail.com).
 * <p>
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl-3.0.txt
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jboot.web.handler;

import com.jfinal.aop.Interceptor;
import com.jfinal.core.Action;
import com.jfinal.core.JFinal;
import com.jfinal.handler.Handler;
import com.jfinal.log.Log;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import io.jboot.aop.JbootInjectManager;
import io.jboot.exception.JbootExceptionHolder;
import io.jboot.web.RequestManager;
import io.jboot.web.session.JbootServletRequestWrapper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class JbootHandler extends Handler {
    static Log log = Log.getLog(JbootHandler.class);
    static String[] urlPara = {null};

    @Override
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {

        if (target.indexOf('.') != -1) {
            return;
        }


        /**
         * 初始化 当前线程的 Hystrix
         */
        HystrixRequestContext context = HystrixRequestContext.initializeContext();


        /**
         * 通过 RequestManager 去保存 request，然后可以在当前线程的任何地方
         * 通过 RequestManager.me().getRequest() 去获取。
         */
        RequestManager.me().handle(request, response);

        /**
         * 初始化 异常记录器，用于记录异常信息，然后在页面输出
         */
        JbootExceptionHolder.init();


        try {

            /**
             * 执行请求逻辑
             */
            doHandle(target, new JbootServletRequestWrapper(request), response, isHandled);

        } finally {
            try {
                context.shutdown();
            } catch (Throwable ex) {
                log.error(ex.toString(), ex);
            }

            try {
                RequestManager.me().release();
            } catch (Throwable ex) {
                log.error(ex.toString(), ex);
            }

            try {
                JbootExceptionHolder.release();
            } catch (Throwable ex) {
                log.error(ex.toString(), ex);
            }
        }

    }

    private void doHandle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        try {
            request.setAttribute("REQUEST", request);
            request.setAttribute("CPATH", request.getContextPath());
            injectInterceptors(target);
        } catch (Throwable ex) {
            log.error(ex.toString(), ex);
        } finally {
            next.handle(target, request, response, isHandled);
        }
    }

    /**
     * 对所有拦截器进行注入
     *
     * @param target
     */
    private void injectInterceptors(String target) {
        Action action = JFinal.me().getAction(target, urlPara);
        Interceptor[] interceptors = action.getInterceptors();
        if (interceptors != null && interceptors.length > 0) {
            for (Interceptor interceptor : interceptors) {
                JbootInjectManager.me().getInjector().injectMembers(interceptor);
            }
        }
    }


}

@@ -1193,16 +1193,42 @@
 sponse;%0A
+import java.util.HashSet;%0A
 %0A%0Apublic
@@ -3322,16 +3322,77 @@
 lPara);%0A
+        if (action == null) %7B%0A            return;%0A        %7D%0A%0A
         
@@ -3475,18 +3475,18 @@
 ors 
-!
+=
 = null 
-&&
+%7C%7C
  int
@@ -3502,17 +3502,18 @@
 .length 
-%3E
+==
  0) %7B%0A  
@@ -3506,32 +3506,160 @@
 gth == 0) %7B%0A    
+        return;%0A        %7D%0A%0A        //%E5%A6%82%E6%9E%9C%E6%B3%A8%E5%85%A5%E8%BF%87%E4%BA%86%EF%BC%8C%E5%B0%B1%E6%B2%A1%E5%BF%85%E8%A6%81%E5%86%8D%E6%AC%A1%E6%B3%A8%E5%85%A5%0A        if (injectFlags.contains(target)) %7B%0A            return;%0A        %7D%0A%0A
         for (Int
@@ -3693,28 +3693,24 @@
 rceptors) %7B%0A
-    
             
@@ -3787,29 +3787,186 @@
     
+%7D%0A%0A        injectFlags.add(target);%0A
     %7D%0A
+%0A
     
-    %7D%0A    %7D
+/**%0A     * %E7%94%A8%E4%BA%8E%E8%AE%B0%E5%BD%95%E6%8B%A6%E6%88%AA%E5%99%A8%E6%98%AF%E5%90%A6%E8%A2%AB%E6%B3%A8%E5%85%A5%E8%BF%87%EF%BC%8C%0A     * %E6%8B%A6%E6%88%AA%E5%99%A8%E5%B1%9E%E4%BA%8E%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F%EF%BC%8C%E6%B3%A8%E5%85%A5%E8%BF%87%E4%B8%80%E6%AC%A1%E5%B0%B1%E6%B2%A1%E5%BF%85%E8%A6%81%E5%86%8D%E6%AC%A1%E6%B3%A8%E5%85%A5%E4%BA%86%0A     */%0A    private static HashSet%3CString%3E injectFlags = new HashSet%3C%3E();
 %0A%0A%0A%7D

优化：优化拦截器注入性能