/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.felix.http.base.internal.handler;

import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletRequest;

import org.osgi.service.http.HttpContext;

final class ServletHandlerRequest
    extends HttpServletRequestWrapper
{
    private final String alias;
    private String pathInfo;
    private boolean pathInfoCalculated = false;

    public ServletHandlerRequest(HttpServletRequest req, String alias)
    {
        super(req);
        this.alias = alias;
    }

    @Override
    public String getAuthType()
    {
        String authType = (String) getAttribute(HttpContext.AUTHENTICATION_TYPE);
        if (authType != null) {
            return authType;
        }

        return super.getAuthType();
    }

    @Override
    public String getPathInfo()
    {
        if (!this.pathInfoCalculated) {
            this.pathInfo = calculatePathInfo();
            this.pathInfoCalculated = true;
        }

        return this.pathInfo;
    }

    @Override
    public String getPathTranslated()
    {
        final String info = getPathInfo();
        return (null == info) ? null : getRealPath(info);
    }

    @Override
    public String getRemoteUser()
    {
        String remoteUser = (String) getAttribute(HttpContext.REMOTE_USER);
        if (remoteUser != null) {
            return remoteUser;
        }

        return super.getRemoteUser();
    }

    @Override
    public String getServletPath()
    {
        if ("/".equals(this.alias)) {
            return "";
        }
        return this.alias;
    }

    private String calculatePathInfo()
    {
        /*
         * The pathInfo from the servlet container is
         *       servletAlias + pathInfo
         * where pathInfo is either an empty string (in which case the
         * client directly requested the servlet) or starts with a slash
         * (in which case the client requested a child of the servlet).
         *
         * Note, the servlet container pathInfo may also be null if the
         * servlet is registered as the root servlet
         */

        String pathInfo = super.getPathInfo();
        if (pathInfo != null) {

            // cut off alias of this servlet (if not the root servlet)
            if (!"/".equals(alias)) {
                pathInfo = pathInfo.substring(alias.length());
            }

            // ensure empty string is coerced to null
            if (pathInfo.length() == 0) {
                pathInfo = null;
            }

        }

        return pathInfo;
    }
}

@@ -1095,24 +1095,56 @@
 ring alias;%0A
+    private String contextPath;%0A
     private 
@@ -1582,32 +1582,706 @@
 hType();%0A    %7D%0A%0A
+    @Override%0A    public String getContextPath()%0A    %7B%0A        /*%0A         * FELIX-2030 Calculate the context path for the Http Service%0A         * registered servlets from the container context and servlet paths%0A         */%0A        if (contextPath == null) %7B%0A            final String context = super.getContextPath();%0A            final String servlet = super.getServletPath();%0A            if (context.length() == 0) %7B%0A                contextPath = servlet;%0A            %7D else if (servlet.length() == 0) %7B%0A                contextPath = context;%0A            %7D else %7B%0A                contextPath = context + servlet;%0A            %7D%0A        %7D%0A%0A        return contextPath;%0A    %7D%0A%0A
     @Override%0A  

FELIX-2030 Calculate the context path from the actual context path and the servlet path of the "servlet" registered in the container.