org.echocat.nodoodle.server.HttpServer.java Source code

Java tutorial

Introduction

Here is the source code for org.echocat.nodoodle.server.HttpServer.java

Source

/*****************************************************************************************
 * *** BEGIN LICENSE BLOCK *****
 *
 * Version: MPL 2.0
 *
 * echocat NoDoodle, Copyright (c) 2010-2012 echocat
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * *** END LICENSE BLOCK *****
 ****************************************************************************************/

package org.echocat.nodoodle.server;

import org.apache.commons.collections.CollectionUtils;
import org.echocat.nodoodle.server.connector.HttpConnector;
import org.echocat.nodoodle.server.utils.DelegatingWebApplicationContext;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

import static org.apache.commons.lang.StringUtils.isEmpty;

public class HttpServer implements ApplicationContextAware, InitializingBean, DisposableBean {

    private static final Logger LOG = LoggerFactory.getLogger(HttpServer.class);

    private Collection<Context<HttpService>> _contexts;
    private Collection<HttpConnector> _connectors;
    private ApplicationContext _applicationContext;

    private Server _jettyServer;

    public Collection<Context<HttpService>> getContexts() {
        return _contexts;
    }

    public void setContexts(Collection<Context<HttpService>> contexts) {
        _contexts = contexts;
    }

    public Collection<HttpConnector> getConnectors() {
        return _connectors;
    }

    public void setConnectors(Collection<HttpConnector> connectors) {
        _connectors = connectors;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        _applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (_applicationContext == null) {
            throw new IllegalStateException("No applicationContext property set.");
        }
        if (CollectionUtils.isEmpty(_connectors)) {
            throw new IllegalStateException("No connectors property with connectors set.");
        }
        if (CollectionUtils.isEmpty(_contexts)) {
            throw new IllegalStateException("No contexts property with connectors set.");
        }
        if (_jettyServer == null) {
            final Server server = new Server();
            for (HttpConnector httpConnector : _connectors) {
                final Connector jettyConnector = httpConnector.createJettyConnector();
                server.addConnector(jettyConnector);
            }

            final ContextHandlerCollection handlerCollection = new ContextHandlerCollection();
            for (Context<HttpService> httpContext : _contexts) {
                final String path = httpContext.getPath();
                final HttpService service = httpContext.getService();
                if (isEmpty(path)) {
                    throw new IllegalArgumentException(
                            "The httpContext " + httpContext + " has no path configured.");
                }
                if (service == null) {
                    throw new IllegalArgumentException(
                            "The httpContext " + httpContext + " has no service configured.");
                }
                final ContextHandler contextHandler = new ContextHandler(path);
                final ServletContext servletContext = contextHandler.getServletContext();
                servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
                        new DelegatingWebApplicationContext(_applicationContext, servletContext));
                service.init(servletContext);
                contextHandler.setHandler(new HandlerImpl(service));
                handlerCollection.addHandler(contextHandler);
            }
            server.setHandler(handlerCollection);

            server.start();
            _jettyServer = server;
        }
    }

    @Override
    public void destroy() throws Exception {
        if (_jettyServer != null) {
            _jettyServer.stop();
        }
    }

    protected class HandlerImpl extends AbstractHandler {

        private final HttpService _service;

        protected HandlerImpl(HttpService service) {
            _service = service;
        }

        @Override
        protected void doStop() throws Exception {
            try {
                try {
                    _service.destroy();
                } catch (Exception e) {
                    LOG.warn("Could not clean shutdown " + _service + ".", e);
                }
            } finally {
                super.doStop();
            }
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request,
                HttpServletResponse response) throws IOException, ServletException {
            _service.handle(request, response);
            baseRequest.setHandled(true);
        }
    }
}