This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 97b55e4bec FELIX-6626 : Support jakarta servlet registration
97b55e4bec is described below

commit 97b55e4bec1ad4fa91cfb07c211f090455f185a1
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Wed Aug 16 15:47:33 2023 +0200

    FELIX-6626 : Support jakarta servlet registration
---
 webconsole/pom.xml                                 |  19 +++-
 .../internal/servlet/JakartaServletTracker.java    | 100 +++++++++++++++++++++
 .../felix/webconsole/internal/servlet/Plugin.java  |   6 +-
 .../webconsole/internal/servlet/PluginHolder.java  |  23 ++++-
 4 files changed, 143 insertions(+), 5 deletions(-)

diff --git a/webconsole/pom.xml b/webconsole/pom.xml
index 7f044c4fd7..a373d50a11 100644
--- a/webconsole/pom.xml
+++ b/webconsole/pom.xml
@@ -117,6 +117,8 @@
                         <Import-Package>
                             javax.servlet.*;version="[3,5)",
                             !javax.portlet,
+                            !jakarta.servlet,
+                            !org.apache.felix.http.javaxwrappers,
                             !org.apache.felix.bundlerepository,
                             !org.osgi.service.obr,
                             !org.osgi.service.cm,
@@ -138,7 +140,9 @@
                             org.osgi.service.metatype;version="[1.4,2)",
                             org.osgi.service.permissionadmin;version="[1.2,2)",
                             org.osgi.service.prefs;version="[1.1,2)",
-                            org.osgi.service.wireadmin;version="[1.0,2)"
+                            org.osgi.service.wireadmin;version="[1.0,2)",
+                            jakarta.servlet;version="[1,2)",
+                            org.apache.felix.http.javaxwrappers;version="[4,6)"
                         </DynamicImport-Package>
                         <Embed-Dependency>
                             
org.apache.felix.utils;inline=org/apache/felix/utils/manifest/**,
@@ -354,7 +358,18 @@
             <version>3.0.1</version>
             <scope>provided</scope>
         </dependency>
-
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <version>5.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.http.wrappers</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>commons-fileupload</groupId>
             <artifactId>commons-fileupload</artifactId>
diff --git 
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
 
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
new file mode 100644
index 0000000000..277e5548f8
--- /dev/null
+++ 
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/JakartaServletTracker.java
@@ -0,0 +1,100 @@
+/*
+ * 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.webconsole.internal.servlet;
+
+
+import java.io.Closeable;
+
+import org.apache.felix.http.javaxwrappers.ServletWrapper;
+import org.apache.felix.webconsole.WebConsoleConstants;
+import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.internal.servlet.Plugin.ServletPlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import jakarta.servlet.Servlet;
+
+public class JakartaServletTracker implements Closeable, 
ServiceTrackerCustomizer<Servlet, JakartaServletTracker.JakartaServletPlugin> {
+
+    private final ServiceTracker<Servlet, JakartaServletPlugin> servletTracker;
+
+    private final PluginHolder pluginHolder;
+
+    public JakartaServletTracker( final PluginHolder pluginHolder, final 
BundleContext context ) {
+        this.pluginHolder = pluginHolder;
+        Filter filter = null;
+        try {
+            filter = context.createFilter("(&(" + Constants.OBJECTCLASS + "=" 
+ Servlet.class.getName() + 
+                ")(" + WebConsoleConstants.PLUGIN_LABEL + "=*))");
+        } catch (final InvalidSyntaxException e) {
+            // not expected, thus fail hard
+            throw new InternalError( "Failed creating filter: " + 
e.getMessage() );
+        }
+        this.servletTracker = new ServiceTracker<>(context, filter, this);
+        servletTracker.open();
+    }
+
+    @Override
+    public void close() {
+        servletTracker.close();
+    }
+
+    @Override
+    public JakartaServletPlugin addingService( final 
org.osgi.framework.ServiceReference<Servlet> reference ) {
+        final String label = Util.getStringProperty( reference, 
WebConsoleConstants.PLUGIN_LABEL );
+        if ( label != null ) {
+            final JakartaServletPlugin plugin = new 
JakartaServletPlugin(this.pluginHolder, reference, label);
+            pluginHolder.addPlugin(plugin);
+            return plugin;
+        }
+        return null;
+    }
+
+    @Override
+    public void modifiedService( final 
org.osgi.framework.ServiceReference<Servlet> reference, final 
JakartaServletPlugin service ) {
+        this.removedService(reference, service);
+        this.addingService(reference);
+    }
+
+    @Override
+    public void removedService( final 
org.osgi.framework.ServiceReference<Servlet> reference, final 
JakartaServletPlugin service ) {
+        this.pluginHolder.removePlugin(service);
+    }
+
+    public static class JakartaServletPlugin extends ServletPlugin {
+            
+        public JakartaServletPlugin(PluginHolder holder, 
ServiceReference<jakarta.servlet.Servlet> serviceReference,
+                String label) {
+            super(holder, (ServiceReference)serviceReference, label);
+        }
+
+        protected javax.servlet.Servlet getService() {
+            final Servlet servlet = (Servlet) 
getHolder().getBundleContext().getService( 
(ServiceReference)this.getServiceReference() );
+            if (servlet != null) {
+                return new ServletWrapper(servlet);
+            }
+            return null;
+        }
+    }
+}
diff --git 
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
 
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
index 65f0366c2b..d234970b43 100644
--- 
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
+++ 
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/Plugin.java
@@ -194,8 +194,12 @@ public abstract class Plugin implements ServletConfig, 
Comparable<Plugin> {
             return this.getServiceReference().toString();
         }
 
+        protected Servlet getService() {
+            return getHolder().getBundleContext().getService( 
this.getServiceReference() );
+        }
+
         protected AbstractWebConsolePlugin doGetConsolePlugin() {
-            final Servlet service = getHolder().getBundleContext().getService( 
this.getServiceReference() );
+            final Servlet service = getService();
             if ( service != null ) {
                 this.title = Util.getStringProperty( 
this.getServiceReference(), WebConsoleConstants.PLUGIN_TITLE );
                 this.category = Util.getStringProperty( 
this.getServiceReference(), WebConsoleConstants.PLUGIN_CATEGORY );
diff --git 
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
 
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
index 198dbc02ce..c5e06396c6 100644
--- 
a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
+++ 
b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/PluginHolder.java
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.webconsole.internal.servlet;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -67,6 +69,8 @@ class PluginHolder implements 
ServiceTrackerCustomizer<Servlet, Plugin> {
 
     private final ServiceTracker<Servlet, Plugin> servletTracker;
 
+    private volatile Closeable jakartaTracker;
+
     PluginHolder( final OsgiManager osgiManager, final BundleContext context ) 
{
         this.osgiManager = osgiManager;
         this.bundleContext = context;
@@ -91,6 +95,13 @@ class PluginHolder implements 
ServiceTrackerCustomizer<Servlet, Plugin> {
      */
     void open() {
         this.servletTracker.open();
+        try {
+            this.jakartaTracker = new JakartaServletTracker(this, 
this.getBundleContext());
+            this.osgiManager.log(LogService.LOG_INFO, "Jakarta Servlet bridge 
enabled");
+        } catch ( final Throwable t) {
+            // ignore
+            this.osgiManager.log(LogService.LOG_INFO, "Jakarta Servlet bridge 
not enabled");
+        }
     }
 
     /**
@@ -99,6 +110,14 @@ class PluginHolder implements 
ServiceTrackerCustomizer<Servlet, Plugin> {
      * held plugin services.
      */
     void close() {
+        if (this.jakartaTracker != null) {
+            try {
+                this.jakartaTracker.close();
+            } catch (final IOException e) {
+                // ignore
+            }
+            this.jakartaTracker = null;
+        }
         this.servletTracker.close();
 
         this.plugins.clear();
@@ -350,7 +369,7 @@ class PluginHolder implements 
ServiceTrackerCustomizer<Servlet, Plugin> {
         removePlugin( plugin );
     }
 
-    private void addPlugin( final Plugin plugin ) {
+    void addPlugin( final Plugin plugin ) {
         synchronized ( plugins ) {
             final List<Plugin> list = 
plugins.computeIfAbsent(plugin.getLabel(), k -> new ArrayList<>());
             final Plugin oldPlugin = list.isEmpty() ? null : list.get(0);
@@ -375,7 +394,7 @@ class PluginHolder implements 
ServiceTrackerCustomizer<Servlet, Plugin> {
         }
     }
 
-    private void removePlugin( final Plugin plugin ) {
+    void removePlugin( final Plugin plugin ) {
         synchronized ( plugins ) {
             final List<Plugin> list = plugins.get( plugin.getLabel() );
             if ( list != null ) {

Reply via email to