/******************************************************************************* * Copyright (c) 2015 IBH SYSTEMS GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBH SYSTEMS GmbH - initial API and implementation *******************************************************************************/ package org.eclipse.packagedrone.web.dispatcher; import java.io.File; import java.io.IOException; import javax.servlet.MultipartConfigElement; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.eclipse.equinox.jsp.jasper.JspServlet; import org.ops4j.pax.web.service.WebContainer; import org.osgi.framework.Bundle; import org.osgi.service.http.NamespaceException; /** * Register a servlet and add JSP support * <p> * <em>Note:</em> All JSPs must be located under <code>/WEB-INF/views</code> * </p> */ public abstract class JspServletInitializer { public static class BundleServletWrapper extends ServletWrapper { private final Bundle bundle; public BundleServletWrapper ( final Servlet servlet, final Bundle bundle ) { super ( servlet ); this.bundle = bundle; } @Override public void service ( final ServletRequest request, final ServletResponse response ) throws ServletException, IOException { if ( request instanceof HttpServletRequest ) { super.service ( new BundleRequestWrapper ( (HttpServletRequest)request, this.bundle ), response ); } else { super.service ( request, response ); } } } public static class BundleRequestWrapper extends HttpServletRequestWrapper { private final Bundle bundle; public BundleRequestWrapper ( final HttpServletRequest request, final Bundle bundle ) { super ( request ); this.bundle = bundle; } @Override public RequestDispatcher getRequestDispatcher ( String path ) { if ( path != null && path.startsWith ( "/WEB-INF" ) ) { path = String.format ( "/bundle/%d%s", this.bundle.getBundleId (), path ); } return super.getRequestDispatcher ( path ); } } private WebContainer httpService; private DispatcherHttpContext webctx; private JspServlet jspServlet; private final String alias; private Servlet servlet; private final Bundle bundle; protected abstract Servlet createServlet (); public JspServletInitializer ( final String alias, final Bundle bundle ) { this.alias = !alias.endsWith ( "/" ) ? alias : alias.substring ( 0, alias.length () - 1 ); this.bundle = bundle; } public void setHttpService ( final WebContainer httpService ) { this.httpService = httpService; } public void start () throws ServletException, NamespaceException { this.webctx = Dispatcher.createContext ( this.bundle.getBundleContext () ); this.servlet = new BundleServletWrapper ( createServlet (), this.bundle ); this.httpService.registerServlet ( this.alias, this.servlet, null, this.webctx ); this.jspServlet = new JspServlet ( this.bundle, "/WEB-INF/views", String.format ( "/bundle/%d/WEB-INF/views", this.bundle.getBundleId () ) ); this.httpService.registerServlet ( this.jspServlet, new String[] { "*.jsp" }, null, this.webctx ); } public void stop () { this.httpService.unregisterServlet ( this.jspServlet ); this.httpService.unregisterServlet ( this.servlet ); this.webctx.dispose (); } public static MultipartConfigElement createMultiPartConfiguration ( final String prefix ) { final String location = System.getProperty ( prefix + ".location", System.getProperty ( "java.io.tmpdir" ) + File.separator + prefix ); final long maxFileSize = Long.getLong ( prefix + ".maxFileSize", 1 * 1024 * 1024 * 1024 /* 1GB */ ); final long maxRequestSize = Long.getLong ( prefix + ".maxRequestSize", 1 * 1024 * 1024 * 1024/* 1GB */ ); final int fileSizeThreshold = Integer.getInteger ( prefix + ".fileSizeThreshold", 10 * 1024 * 1024 /* 10 MB */ ); return new MultipartConfigElement ( location, maxFileSize, maxRequestSize, fileSizeThreshold ); } }