Package com.blogger.tcuri.appserver

Source Code of com.blogger.tcuri.appserver.AppServer

package com.blogger.tcuri.appserver;

import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.logging.Logger;

import com.blogger.tcuri.appserver.config.AbstractAppConfig;
import com.blogger.tcuri.appserver.interceptor.Interceptor;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

/**
* アプリケーションサーバの主体となるクラスです
*
* @author tomofumi
*/
public class AppServer {

    /**
     * 空きポートを探す最大回数
     */
    protected static final int SERACH_PORT_TIMES = 10;

    /**
     * Interceptorのインスタンスのリスト
     */
    protected static final List<Interceptor> interceptorList = new ArrayList<Interceptor>();

    /**
     * AbstractAppConfigのオブエジェクト
     */
    protected static AbstractAppConfig appConfig;

    /**
     * Frameworkクラスのインスタンス
     */
    protected static Framework framework;

    /**
     * Loggerクラスのインスタンス
     */
    protected static Logger logger = Logger
            .getLogger(Logger.GLOBAL_LOGGER_NAME);

    /**
     * アプリケーションサーバを起動する
     *
     * @throws Exception
     */
    public static void startup() throws Exception {

        framework = new Framework();
        appConfig = framework.appConfig;

        long startTime = new Date().getTime();

        HttpServer server = null;
        Integer port = appConfig.getPort();
        if (port == null) {
            //
            // port auto の場合
            //
            port = 8081;
            for (int i = 0; i < SERACH_PORT_TIMES; i++) { // 空きポートを探す回数
                port += i;
                try {
                    server = HttpServer.create(new InetSocketAddress(
                            "localhost", port), 0);
                } catch (BindException e) {
                    continue;
                }
                break;
            }
        } else {
            server = HttpServer.create(
                    new InetSocketAddress("localhost", port), 0);
        }

        server.setExecutor(Executors.newCachedThreadPool());

        server.createContext("/", new HttpHandler() {
            public void handle(HttpExchange he) throws IOException {
                ActionContext context = new ActionContextImpl(he);
                String path = he.getRequestURI().getPath();
                // 拡張子なしをデフォルトでActionとして扱う。
                if (path.indexOf('.') == -1) {
                    framework.processDynamicResource(context);
                } else {
                    processStaticResource(context);
                }
                ActionContext.remove();
            }
        });

        server.start();
        logger.info("port: " + port);

        String browserInitPath = appConfig.getBrowserInitPath();
        if (browserInitPath != null) {
            String url = "http://localhost:" + port + browserInitPath;
            Desktop.getDesktop().browse(new URI(url));
            logger.info("browser init path: " + url);
        }

        logger.info(String.format("Server startup in %d ms",
                new Date().getTime() - startTime));
    }

    /**
     * 静的リソースをHTTPレスポンスする
     *
     * @param context
     *            {@link ActionContext} クラスのインスタンス
     * @throws IOException
     */
    private static void processStaticResource(ActionContext context)
            throws IOException {

        String path = context.getRequestPath();
        URL url = AppServer.class.getResource("/documentRoot" + path);
        File f = new File(url.getFile());

        if (!f.exists()) {
            // ファイルがない
            context.sendResponseHeaders(404, 0);
            context.sendMessage("not found.");
            return;
        }
        if (f.isDirectory()) {
            // TODO 通らない。。
            File indexFile = new File(f, "index.html");
            if (!indexFile.exists()) {
                // ディレクトリは見れない
                context.sendResponseHeaders(403, 0);
                context.sendMessage("fobbiden.");
                return;
            }
            f = indexFile;
        }

        int idx = path.lastIndexOf(".");
        if (idx >= 0) {
            // 拡張子からmimeタイプを出力
            String ext = path.substring(idx + 1);
            String mimetype = appConfig.getMimetype(ext);
            if (mimetype != null) {
                context.addResponseHeader("Content-Type", mimetype);
            }
        }

        context.sendResponseHeaders(200, f.length());
        // ファイル内容を返す
        InputStream is = new FileInputStream(f);
        OutputStream res = context.getResponseBody();
        try {
            byte[] buf = new byte[1024];
            int len;
            while ((len = is.read(buf)) >= 0) {
                res.write(buf, 0, len);
            }
        } finally {
            res.close();
            is.close();
        }
    }

    /**
     * メインメソッドです
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        startup();
    }
}
TOP

Related Classes of com.blogger.tcuri.appserver.AppServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.