Package com.jfinal.server

Source Code of com.jfinal.server.JettyServer

/**
* Copyright (c) 2011-2012, James Zhan 詹波 (jfinal@126.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* 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 com.jfinal.server;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.management.MBeanServer;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.management.MBeanContainer;
import org.mortbay.util.Scanner;
import com.jfinal.util.PathUtil;

/**
* JettyServer is used to config and start jetty web server.
* Jetty version 6.1.26
*/
/*
* 1: project dir (no use)
* 2: port
* 3: context
* 4: webapp dir
* 5: scan interval senconds
*/
class JettyServer implements IServer {
 
  private String webAppDir;
  private int port;
  private String context;
  private int scanIntervalSeconds;
  private boolean isStarted = false;
  private Server server;
  private WebAppContext web;
  private boolean enablescanner = true;
 
  JettyServer(String webAppDir, int port, String context, int scanIntervalSeconds) {
    this.webAppDir = webAppDir;
    this.port = port;
    this.context = context;
    this.scanIntervalSeconds = scanIntervalSeconds;
    checkConfig();
  }
 
  private void checkConfig() {
    if (port < 0 || port > 65536)
      throw new IllegalArgumentException("Invalid port of web server: " + port);
   
    if (scanIntervalSeconds < 1)
      enablescanner = false;
   
    if (context == null)
      throw new IllegalStateException("Invalid context of web server: " + context);
   
    if (webAppDir == null)
      throw new IllegalStateException("Invalid context of web server: " + webAppDir);
  }
 
  public void start() {
    if (! isStarted) {
      try {
        doStart();
      } catch (Exception e) {
        e.printStackTrace();
      }
      isStarted = true;
    }
    else {
      throw new RuntimeException("Server already started.");
    }
  }
 
  private void doStart() throws Exception {
    String context = this.context;
    String webAppDir = this.webAppDir;
    Integer port = this.port;
    Integer scanIntervalSeconds = this.scanIntervalSeconds;
   
    server = new Server();
   
    if (port != null) {
      if (!available(port)) {
        throw new IllegalStateException("port: " + port + " already in use!");
      }
      SelectChannelConnector connector = new SelectChannelConnector();
      connector.setPort(port);
     
      server.addConnector(connector);
    }
   
    web = new WebAppContext();
   
    // 警告: 设置成 true 无法支持热加载
    // web.setParentLoaderPriority(false);
    web.setContextPath(context);
    web.setWar(webAppDir);
    web.setInitParams(Collections.singletonMap("org.mortbay.jetty.servlet.Default.useFileMappedBuffer", "false"));
    server.addHandler(web);
   
    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
    server.getContainer().addEventListener(mBeanContainer);
    mBeanContainer.start();
   
    // configureScanner
    if (enablescanner) {
      final ArrayList<File> scanList = new ArrayList<File>();
      scanList.add(new File(PathUtil.getRootClassPath()));
      Scanner scanner = new Scanner();
      scanner.setReportExistingFilesOnStartup(false);
      scanner.setScanInterval(scanIntervalSeconds);
      scanner.setScanDirs(scanList);
      scanner.addListener(new Scanner.BulkListener() {
       
        public void filesChanged(@SuppressWarnings("rawtypes") List changes) {
          try {
            System.err.println("Loading changes ......");
            web.stop();
            web.start();
            System.err.println("Loading complete.\n");
           
          } catch (Exception e) {
            System.err.println("Error reconfiguring/restarting webapp after change in watched files");
            e.printStackTrace();
          }
        }
      });
      System.err.println("Starting scanner at interval of " + scanIntervalSeconds + " seconds.");
      scanner.start();
    }
   
    try {
      server.start();
      server.join();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(100);
    }
    return;
  }
 
  private static boolean available(int port) {
    if (port <= 0) {
      throw new IllegalArgumentException("Invalid start port: " + port);
    }
   
    ServerSocket ss = null;
    DatagramSocket ds = null;
    try {
      ss = new ServerSocket(port);
      ss.setReuseAddress(true);
      ds = new DatagramSocket(port);
      ds.setReuseAddress(true);
      return true;
    } catch (IOException e) {
    } finally {
      if (ds != null) {
        ds.close();
      }
     
      if (ss != null) {
        try {
          ss.close();
        } catch (IOException e) {
          // should not be thrown, just detect port available.
        }
      }
    }
    return false;
  }
}






TOP

Related Classes of com.jfinal.server.JettyServer

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.