/**
 * The MIT License
 *
 * Copyright (c) 2010-2011 Sonatype, Inc. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package org.hudsonci.servlets.internal;

import org.hudsonci.servlets.ServletRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Wraps a {@link Servlet} as a {@link Filter} for installation via {@link hudson.util.PluginServletFilter}.
 *
 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
 * @since 2.1.0
 */
public class ServletRegistrationFilterAdapter
    implements Filter
{
    private static final Logger log = LoggerFactory.getLogger(ServletRegistrationFilterAdapter.class);

    private final ServletRegistration registration;

    private final Servlet servlet;

    private final String uriPrefix;

    private boolean enabled;

    public ServletRegistrationFilterAdapter(final ServletRegistration registration) throws Exception {
        this.registration = checkNotNull(registration);
        this.servlet = createServlet();

        if (registration.getName() == null) {
            registration.setName(servlet.getClass().getName());
        }

        uriPrefix = registration.getUriPrefix();
        if (uriPrefix == null) {
            throw new IllegalArgumentException("Registration missing uriPrefix");
        }
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(final boolean enabled) {
        this.enabled = enabled;
    }

    private Servlet createServlet() throws Exception {
        Servlet servlet = registration.getServlet();
        if (servlet != null) {
            return servlet;
        }

        Class<? extends Servlet> type = registration.getServletType();
        if (type != null) {
            return type.newInstance();
        }

        throw new IllegalArgumentException("Registration missing servlet or servlet type");
    }

    public void init(final FilterConfig config) throws ServletException {
        checkNotNull(config);

        servlet.init(new ServletConfig()
        {
            public String getServletName() {
                return registration.getName();
            }

            public ServletContext getServletContext() {
                return config.getServletContext();
            }

            public Enumeration getInitParameterNames() {
                final Iterator<String> iter = registration.getParameters().keySet().iterator();

                return new Enumeration()
                {
                    public boolean hasMoreElements() {
                        return iter.hasNext();
                    }

                    public Object nextElement() {
                        return iter.next();
                    }
                };
            }

            public String getInitParameter(final String name) {
                return registration.getParameters().get(name);
            }
        });
    }

    public void destroy() {
        servlet.destroy();
    }

    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
        throws IOException, ServletException
    {
        assert chain != null;

        if (isEnabled() && request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
        }
        else {
            chain.doFilter(request, response);
        }
    }

    private void doFilter(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain)
        throws IOException, ServletException
    {
        assert request != null;
        assert response != null;
        assert chain != null;

        String uri = request.getRequestURI();

        // Get the requestUri without the context uriPrefix and the leading slash
        uri = uri.substring(request.getContextPath().length());

        if (uri.startsWith(uriPrefix)) {
            // Wrap the request to augment the servlet uriPrefix
            HttpServletRequestWrapper req = new HttpServletRequestWrapper(request)
            {
                @Override
                public String getServletPath() {
                    return String.format("/%s", uriPrefix);
                }
            };

            servlet.service(req, response);
        }
        else {
            chain.doFilter(request, response);
        }
    }
}

@@ -5400,19 +5400,27 @@
  String 
-uri
+contextPath
  = reque
@@ -5429,31 +5429,31 @@
 .get
-RequestURI
+ContextPath
 ();%0A
-%0A
         
 // G
@@ -5452,174 +5452,189 @@
     
-// Get the requestUri without the context uriPrefix and the leading slash%0A        uri = uri.substring(request.getContextPath().length());%0A%0A        if (uri.startsWith(
+if (!contextPath.endsWith(%22/%22) && !uriPrefix.startsWith(%22/%22)) %7B%0A            contextPath = contextPath + '/';%0A        %7D%0A%0A        if (request.getRequestURI().startsWith(contextPath + 
 uriP

make URI parsing more robust