/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.deployment.web;

import java.io.File;

import org.jfox.framework.deploy.DeployException;
import org.jfox.framework.extra.Managable;
import org.jfox.framework.extra.ManagementInfo;
import org.mortbay.http.HttpContext;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.WebApplicationContext;
import org.mortbay.util.Log;


/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class JettyWebContainer extends AbstractWebContainer implements Managable {
    private Server server;
    private JettyLogSink logSink = null;

    private String jettyConfig = "../conf/jetty.xml";

    public JettyWebContainer(String jettyConfig) {
        this.jettyConfig = jettyConfig;
    }

    protected void doDeploy(WebModule webModule) throws DeployException {
        try {
            WebApplicationContext webApp = new JettyWebApplicationContext(webModule.getTempDeployDirectory().getCanonicalPath());
            webApp.setTempDirectory(webModule.getTempDeployDirectory());
            if(webModule.getWebContext().equals(server.getRootWebApp())) {
                webApp.setContextPath("/");
            }
            else {
                webApp.setContextPath("/" + webModule.getWebContext());
            }
            // set ClassLoader
//      webApp.setClassLoader(webModule.getClassLoader());
            webApp.setParentClassLoader(webModule.getClassLoader());
            webApp.setClassLoaderJava2Compliant(true);
            server.addContext(webApp);
            webApp.start();
        }
        catch(Exception e) {
            throw new DeployException("deploy web module " + webModule.getWebContext() + " failed", e);
        }
    }

    protected void doUndeploy(WebModule webModule) {
        HttpContext httpContext = server.getContext(webModule.getWebContext());
        try {
            httpContext.stop(true);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
        server.removeContext(httpContext);
    }

    /**
     * because jetty use Thread context classloader,
     * so must start a new thread, and set the thread context class loader to Module LocalClassLoader
     *
     * @throws Exception
     */
    protected void doStart() throws Exception {
        // set logger, user jfox logger
        Log.instance().disableLog(); // remove default logger
        Log.instance().add(logSink);
        logSink.start();
        Thread thread = new Thread(this);
        thread.setName(getName());
        thread.start();
        thread.join();
    }

    protected void doStop() throws Exception {
        server.stop();
        logSink.stop();
        Log.instance().deleteStoppedLogSinks();
    }

    protected void doInit() throws Exception {
        logSink = new JettyLogSink(logger);
    }

    protected void doDestroy() throws Exception {
        server = null;
        logSink.destroy();
    }

    public void run() {
        // must set the thread context classloader to Module's LocalClassLoader
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        try {
            File conf = new File(jettyConfig);
            server = new Server(conf.toURL());
            if(server.getRootWebApp() == "null" || server.getRootWebApp().equals("")) {
                server.setRootWebApp("root");
            }
            server.start();
        }
        catch(Exception e) {
            logger.warn("start Jetty Web Container error", e);
        }
    }

    public boolean isStarted() {
        return super.isStarted() && server.isStarted();
    }

    public String getConfiguration() {
        return server == null ? null : server.getConfiguration();
    }

    public String getRoot() {
        return server == null ? null : server.getRootWebApp();
    }

    public ManagementInfo getManagementInfo() {
        return ManagementInfo.exposePublic(this.getClass());
    }


    public static void main(String[] args) {

    }
}

