FELIX-3295 Add support for a new org.apache.felix.http.context_path configuration
property to change the context path for the Http Service

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1227558 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
index 6ddfb97..6a642f0 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
@@ -89,7 +89,10 @@
     public static final String FELIX_JETTY_RESPONSE_BUFFER_SIZE = "org.apache.felix.http.jetty.responseBufferSize";
 
     /** Felix specific property to enable Jetty MBeans. Valid values are "true", "false". Default is false */
-    public static final String  FELIX_HTTP_MBEANS = "org.apache.felix.http.mbeans";
+    public static final String FELIX_HTTP_MBEANS = "org.apache.felix.http.mbeans";
+
+    /** Felix specific property to set the servlet context path of the Http Service */
+    public static final String FELIX_HTTP_CONTEXT_PATH = "org.apache.felix.http.context_path";
 
     private final BundleContext context;
     private boolean debug;
@@ -112,6 +115,7 @@
     private int headerBufferSize;
     private int requestBufferSize;
     private int responseBufferSize;
+    private String contextPath;
 
     /**
      * Properties from the configuration not matching any of the
@@ -243,6 +247,11 @@
         return this.responseBufferSize;
     }
 
+    public String getContextPath()
+    {
+        return contextPath;
+    }
+
     public void reset()
     {
         update(null);
@@ -274,6 +283,7 @@
         this.headerBufferSize = getIntProperty(FELIX_JETTY_HEADER_BUFFER_SIZE, 16 * 1024);
         this.requestBufferSize = getIntProperty(FELIX_JETTY_REQUEST_BUFFER_SIZE, 8 * 014);
         this.responseBufferSize = getIntProperty(FELIX_JETTY_RESPONSE_BUFFER_SIZE, 24 * 1024);
+        this.contextPath = validateContextPath(getProperty(props, FELIX_HTTP_CONTEXT_PATH, null));
 
         // copy rest of the properties
         Enumeration keys = props.keys();
@@ -315,6 +325,27 @@
         }
     }
 
+    private static String validateContextPath(String ctxPath)
+    {
+        // undefined, empty, or root context path
+        if (ctxPath == null || ctxPath.length() == 0 || "/".equals(ctxPath))
+        {
+            return "/";
+        }
+
+        // ensure leading but no trailing slash
+        if (!ctxPath.startsWith("/"))
+        {
+            ctxPath = "/".concat(ctxPath);
+        }
+        while (ctxPath.endsWith("/"))
+        {
+            ctxPath = ctxPath.substring(0, ctxPath.length() - 1);
+        }
+
+        return ctxPath;
+    }
+
     /**
      * Returns the named generic configuration property from the
      * configuration or the bundle context. If neither property is defined
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
index aa410c1..ce36439 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
@@ -170,7 +170,8 @@
                 message.append(" HTTPS:").append(this.config.getHttpsPort());
             }
 
-            Context context = new Context(this.server, "/", Context.SESSIONS);
+            Context context = new Context(this.server, this.config.getContextPath(), Context.SESSIONS);
+            message.append(" on context path ").append(this.config.getContextPath());
             configureSessionManager(context);
             context.addEventListener(eventDispatcher);
             context.getSessionHandler().addEventListener(eventDispatcher);
diff --git a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties
index a0f00f6..67b0a34 100644
--- a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -117,3 +117,9 @@
 org.apache.felix.http.jetty.responseBufferSize.name = Response Buffer Size
 org.apache.felix.http.jetty.responseBufferSize.description = Size of the \
  buffer for responses. Default is 24KB.
+
+org.apache.felix.http.context_path.name = Context Path
+org.apache.felix.http.context_path.description = The Servlet Context Path \
+ to use for the Http Service. If this property is not configured it \
+ defaults to "/". This must be a valid path starting with a slash and not \
+ ending with a slash (unless it is the root context).
\ No newline at end of file
diff --git a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml
index 416e020..b418876 100644
--- a/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml
+++ b/http/jetty/src/main/resources/OSGI-INF/metatype/metatype.xml
@@ -27,21 +27,22 @@
         <AD id="org.apache.felix.https.enable" type="Boolean" default="false" name="%org.apache.felix.https.enable.name" description="%org.apache.felix.https.enable.description"/>
         <AD id="org.osgi.service.http.port.secure" type="Integer" default="433" name="%org.osgi.service.http.port.secure.name" description="%org.osgi.service.http.port.secure.description"/>
         <AD id="org.apache.felix.https.nio" type="Boolean" default="true" name="%org.apache.felix.https.nio.name" description="%org.apache.felix.https.nio.description"/>
-        <AD id="org.apache.felix.http.mbeans" type="Boolean" default="false" name="%org.apache.felix.http.mbeans.name" description="%org.apache.felix.http.mbeans.description"/>
         <AD id="org.apache.felix.https.keystore" type="String" name="%org.apache.felix.https.keystore.name" description="%org.apache.felix.https.keystore.description"/>
         <AD id="org.apache.felix.https.keystore.password" type="String" name="%org.apache.felix.https.keystore.password.name" description="%org.apache.felix.https.keystore.password.description"/>
         <AD id="org.apache.felix.https.keystore.key.password" type="String" name="%org.apache.felix.https.keystore.key.password.name" description="%org.apache.felix.https.keystore.key.password.description"/>
         <AD id="org.apache.felix.https.truststore" type="String" name="%org.apache.felix.https.truststore.name" description="%org.apache.felix.https.truststore.description"/>
         <AD id="org.apache.felix.https.truststore.password" type="String" name="%org.apache.felix.https.truststore.password.name" description="%org.apache.felix.https.truststore.password.description"/>
         <AD id="org.apache.felix.https.clientcertificate" type="String" default="none" name="%org.apache.felix.https.clientcertificate.name" description="%org.apache.felix.https.clientcertificate.description">
-        <AD id="org.apache.felix.http.session.timeout" type="Integer" default="0" name="%org.apache.felix.http.session.timeout.name" description="%org.apache.felix.http.session.timeout.description">
-        <AD id="org.apache.felix.http.jetty.headerBufferSize" type="Integer" default="16384" name="%org.apache.felix.http.jetty.headerBufferSize.name" description="%org.apache.felix.http.jetty.headerBufferSize.description">
-        <AD id="org.apache.felix.http.jetty.requestBufferSize" type="Integer" default="8192" name="%org.apache.felix.http.jetty.requestBufferSize.name" description="%org.apache.felix.http.jetty.requestBufferSize.description">
-        <AD id="org.apache.felix.http.jetty.responseBufferSize" type="Integer" default="24576" name="%org.apache.felix.http.jetty.responseBufferSize.name" description="%org.apache.felix.http.jetty.responseBufferSize.description">
             <Option value="none" label="%clientcertificate.none"/>
             <Option value="wants" label="%clientcertificate.wants"/>
             <Option value="needs" label="%clientcertificate.needs"/>
         </AD>
+        <AD id="org.apache.felix.http.context_path" type="String" default="/" name="%org.apache.felix.http.context_path.name" description="%org.apache.felix.http.context_path.description"/>
+        <AD id="org.apache.felix.http.mbeans" type="Boolean" default="false" name="%org.apache.felix.http.mbeans.name" description="%org.apache.felix.http.mbeans.description"/>
+        <AD id="org.apache.felix.http.session.timeout" type="Integer" default="0" name="%org.apache.felix.http.session.timeout.name" description="%org.apache.felix.http.session.timeout.description"/>
+        <AD id="org.apache.felix.http.jetty.headerBufferSize" type="Integer" default="16384" name="%org.apache.felix.http.jetty.headerBufferSize.name" description="%org.apache.felix.http.jetty.headerBufferSize.description"/>
+        <AD id="org.apache.felix.http.jetty.requestBufferSize" type="Integer" default="8192" name="%org.apache.felix.http.jetty.requestBufferSize.name" description="%org.apache.felix.http.jetty.requestBufferSize.description"/>
+        <AD id="org.apache.felix.http.jetty.responseBufferSize" type="Integer" default="24576" name="%org.apache.felix.http.jetty.responseBufferSize.name" description="%org.apache.felix.http.jetty.responseBufferSize.description"/>
         <AD id="org.apache.felix.http.debug" type="Boolean" default="false" name="%org.apache.felix.http.debug.name" description="%org.apache.felix.http.debug.description"/>
     </OCD>
     <Designate pid="org.apache.felix.http">