package org.randomcoder.config;

import java.util.EnumSet;

import javax.inject.Inject;
import javax.servlet.*;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.*;
import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
import org.eclipse.jetty.servlet.ServletContextHandler.JspPropertyGroup;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
import org.randomcoder.log.JettyLog4jLog;
import org.springframework.context.annotation.*;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.*;
import org.springframework.web.servlet.DispatcherServlet;

@Configuration
@SuppressWarnings("javadoc")
public class JettyContext
{
	public static final String HTTP_PORT_PROP = "http.port";
	public static final String HTTP_ADDRESS_PROP = "http.address";
	public static final String HTTP_THREADS_PROP = "http.threads";

	static
	{
		// make sure jetty doesn't try to use slf4j
		Log.setLog(new JettyLog4jLog());
	}

	@Inject
	ConfigurableEnvironment env;

	@Bean(initMethod = "start", destroyMethod = "destroy")
	public Server jettyServer() throws Exception
	{
		Server server = new Server();

		SelectChannelConnector connector = new SelectChannelConnector();
		connector.setHost(env.getRequiredProperty(HTTP_ADDRESS_PROP, String.class));
		connector.setPort(env.getRequiredProperty(HTTP_PORT_PROP, Integer.class));
		connector.setThreadPool(new QueuedThreadPool(env.getRequiredProperty(HTTP_THREADS_PROP, Integer.class)));
		connector.setName("admin");
		connector.setForwarded(true);

		server.addConnector(connector);

		HandlerCollection handlers = new HandlerCollection();

		WebAppContext context = new WebAppContext();
		context.setContextPath("/");
		context.setWelcomeFiles(new String[] { "index.jsp", "index.html" });
		context.getMimeTypes().addMimeMapping("wsdl", "text/xml");
		context.setInitParameter("javax.servlet.jsp.jstl.fmt.localizationContext", "ApplicationResources");
		
		// configure session handling
		context.getSessionHandler().getSessionManager().setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
		context.getSessionHandler().getSessionManager().setMaxInactiveInterval(1800);

		// configure JSP files
		JspPropertyGroup jsppg = new JspPropertyGroup();
		jsppg.addUrlPattern("*.jsp");
		jsppg.setElIgnored("false");
		jsppg.setPageEncoding("UTF-8");
		jsppg.setScriptingInvalid("true");
		JspConfig jspc = new JspConfig();
		jspc.addJspPropertyGroup(jsppg);
		context.getServletContext().setJspConfigDescriptor(jspc);
		
		// figure out where our content lives at runtime
		String resourceBase = getClass().getResource("/webapp/WEB-INF/web.xml").toURI().toString().replaceAll("WEB-INF/web.xml$", "");
		context.setResourceBase(resourceBase);

		// define a root spring context
		AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
		rootContext.setEnvironment(env);
		rootContext.register(RootContext.class);

		context.addEventListener(new ContextLoaderListener(rootContext));

		// define spring security filter
		FilterHolder sec = new FilterHolder();
		sec.setFilter(new DelegatingFilterProxy());
		sec.setName("springSecurityFilterChain");
		context.addFilter(sec, "/*", EnumSet.allOf(DispatcherType.class));
		
		// define etag filter to better cache static content
		FilterHolder etag = new FilterHolder();
		etag.setFilter(new ShallowEtagHeaderFilter());
		etag.setName("etag");
		context.addFilter(etag, "*.js", EnumSet.of(DispatcherType.REQUEST));
		context.addFilter(etag, "*.css", EnumSet.of(DispatcherType.REQUEST));
		context.addFilter(etag, "*.jpg", EnumSet.of(DispatcherType.REQUEST));
		context.addFilter(etag, "*.png", EnumSet.of(DispatcherType.REQUEST));
		context.addFilter(etag, "*.gif", EnumSet.of(DispatcherType.REQUEST));
		
		// define dispatcher servlet
		AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
		dispatcherContext.setParent(rootContext);
		dispatcherContext.setEnvironment(env);
		dispatcherContext.register(DispatcherContext.class);
		dispatcherContext.setEnvironment(env);		
		
		ServletHolder dispatcher = new ServletHolder("springmvc", new DispatcherServlet(dispatcherContext));		
		context.addServlet(dispatcher, "");
		context.addServlet(dispatcher, "/account/*");
		context.addServlet(dispatcher, "/article/*");
		context.addServlet(dispatcher, "/articles/*");
		context.addServlet(dispatcher, "/comment/*");
		context.addServlet(dispatcher, "/download/*");
		context.addServlet(dispatcher, "/feeds/*");
		context.addServlet(dispatcher, "/legal/*");
		context.addServlet(dispatcher, "/login");
		context.addServlet(dispatcher, "/login-error");
		context.addServlet(dispatcher, "/redirect");
		context.addServlet(dispatcher, "/tag/*");
		context.addServlet(dispatcher, "/tags/*");
		context.addServlet(dispatcher, "/user/*");
		
		handlers.addHandler(context);
		server.setHandler(handlers);

		return server;
	}
}
@@ -109,24 +109,70 @@
 rvlet.*;%0D%0A%0D%0A
+import org.apache.jasper.servlet.JspServlet;%0D%0A
 import org.e
@@ -4645,251 +4645,8 @@
 %0D%0A%09%09
-ServletHolder dispatcher = new ServletHolder(%22springmvc%22, new DispatcherServlet(dispatcherContext));%09%09%0D%0A%09%09context.addServlet(dispatcher, %22%22);%0D%0A%09%09context.addServlet(dispatcher, %22/account/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/article/*%22);%0D%0A%09%09
 cont
@@ -4652,32 +4652,51 @@
 text.addServlet(
+new ServletHolder(%22
 dispatcher, %22/ar
@@ -4693,494 +4693,140 @@
 cher
+%22
 , 
-%22/articles/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/comment/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/download/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/feeds/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/legal/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/login%22);%0D%0A%09%09context.addServlet(dispatcher, %22/login-error%22);%0D%0A%09%09context.addServlet(dispatcher, %22/redirect%22);%0D%0A%09%09context.addServlet(dispatcher, %22/tag/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/tags/*%22);%0D%0A%09%09context.addServlet(dispatcher, %22/user
+new DispatcherServlet(dispatcherContext)), %22/*%22);%0D%0A%09%09context.addServlet(new ServletHolder(%22jsp%22, new JspServlet()), %22/WEB-INF/jsp
 /*%22)

simplify jetty context to avoid having to specify multiple URLs