From a6e033c10b3a9a27883b50fe2057ef5ba18c82b8 Mon Sep 17 00:00:00 2001 From: Grzegorz Grzybek Date: Mon, 12 Jun 2023 14:15:52 +0200 Subject: [PATCH] [#1802] Switch pax-web-api from javax to jakarta --- pax-web-api/pom.xml | 115 ++++++----- pax-web-api/readme.adoc | 42 ++-- .../ops4j/pax/web/service/PaxWebConfig.java | 18 +- .../pax/web/service/PaxWebConstants.java | 50 ++--- .../ops4j/pax/web/service/WebContainer.java | 46 ++--- .../pax/web/service/WebContainerContext.java | 38 ++-- .../pax/web/service/http/HttpContext.java | 185 ++++++++++++++++++ .../pax/web/service/http/HttpService.java | 175 +++++++++++++++++ .../web/service/http/NamespaceException.java | 91 +++++++++ .../pax/web/service/http/package-info.java | 27 +++ .../ops4j/pax/web/service/package-info.java | 2 +- .../service/whiteboard/ContextMapping.java | 12 +- .../service/whiteboard/ContextRelated.java | 60 +++--- .../service/whiteboard/ErrorPageMapping.java | 8 +- .../web/service/whiteboard/FilterMapping.java | 6 +- .../whiteboard/HttpContextMapping.java | 4 +- .../service/whiteboard/ResourceMapping.java | 8 +- .../whiteboard/SecurityConstraintMapping.java | 2 +- .../ServletContextHelperMapping.java | 2 +- .../service/whiteboard/ServletMapping.java | 26 +-- .../service/whiteboard/WebSocketMapping.java | 2 +- .../web/service/whiteboard/package-info.java | 4 +- .../pax/web/utils/ClassPathUtilTest.java | 96 ++++----- .../ops4j/pax/web/utils/ClassSpaceTest.java | 2 +- .../java/org/ops4j/pax/web/utils/UrlTest.java | 2 +- 25 files changed, 762 insertions(+), 261 deletions(-) create mode 100644 pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpContext.java create mode 100644 pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpService.java create mode 100644 pax-web-api/src/main/java/org/ops4j/pax/web/service/http/NamespaceException.java create mode 100644 pax-web-api/src/main/java/org/ops4j/pax/web/service/http/package-info.java diff --git a/pax-web-api/pom.xml b/pax-web-api/pom.xml index 13ffd91d29..5e906e35b1 100644 --- a/pax-web-api/pom.xml +++ b/pax-web-api/pom.xml @@ -87,10 +87,10 @@ copy-selected-resources process-resources @@ -101,14 +101,14 @@ ${project.build.outputDirectory}/META-INF/resources - ${project.build.directory}/unpack-deps/tomcat-servlet-api/javax/servlet/resources + ${project.build.directory}/unpack-deps/tomcat-servlet-api/jakarta/servlet/resources *.xsd *.dtd - ${project.build.directory}/unpack-deps/tomcat-jsp-api/javax/servlet/jsp/resources + ${project.build.directory}/unpack-deps/tomcat-jsp-api/jakarta/servlet/jsp/resources *.xsd *.dtd @@ -126,18 +126,26 @@ - - javax.servlet;version="[3.1,5)", - javax.servlet.annotation;version="[3.1,5)", - javax.servlet.http;version="[3.1,5)", + + jakarta.servlet;version="[6,7)", + jakarta.servlet.annotation;version="[6,7)", + jakarta.servlet.http;version="[6,7)", - - org.osgi.dto;version="[1.0,2)", - org.osgi.framework;version="[1.8,2)", + + org.osgi.dto;version="[1.1,2)", + org.osgi.framework;version="[1.10,2)", org.osgi.framework.wiring;version="[1.2,2)", + + org.osgi.service.servlet.context;version="2.0.0", + org.osgi.service.servlet.runtime;version="2.0.0", + org.osgi.service.servlet.runtime.dto;version="2.0.0", + org.osgi.service.servlet.whiteboard;version="2.0.0", + org.osgi.service.servlet.whiteboard.annotations;version="2.0.0", + org.osgi.service.servlet.whiteboard.propertytypes;version="2.0.0", + - org.slf4j;version="[1.7,2)" + org.slf4j;version="[2,3)" @@ -146,18 +154,7 @@ org.ops4j.pax.web.service.whiteboard;version="${pax-web.osgi.version}", org.ops4j.pax.web.utils;version="${pax-web.osgi.version}", - org.ops4j.pax.web.service;version="7.4", - - - org.osgi.service.http;version="1.2.1", - - - org.osgi.service.http.context;version="1.1", - org.osgi.service.http.runtime;version="1.1", - org.osgi.service.http.runtime.dto;version="1.1", - org.osgi.service.http.whiteboard;version="1.1", - org.osgi.service.http.whiteboard.annotations;version="1.1", - org.osgi.service.http.whiteboard.propertytypes;version="1.1" + {maven-resources}, @@ -216,8 +213,23 @@ osgi.core provided + + org.osgi + org.osgi.namespace.extender + provided + + + org.osgi + org.osgi.service.http + provided + + + org.osgi + org.osgi.service.servlet + provided + - + jakarta.servlet @@ -234,38 +246,49 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-slf4j2-impl test - - - - - - - - - - - - - - - - - - + + + org.apache.tomcat + tomcat-servlet-api + provided + + + + org.apache.tomcat + tomcat-jsp-api + provided + + + + org.junit.jupiter + junit-jupiter-api + test + - junit - junit + org.junit.jupiter + junit-jupiter-engine test + + org.assertj + assertj-core + ${dependency.org.assertj} + org.springframework spring-core diff --git a/pax-web-api/readme.adoc b/pax-web-api/readme.adoc index a8175ff16a..f037092e64 100644 --- a/pax-web-api/readme.adoc +++ b/pax-web-api/readme.adoc @@ -3,14 +3,14 @@ This bundle has these purposes: * re-export packages specified in OSGi CMPN R7 102 "Http Service Specification" -** `org.osgi.service.http` 1.2 +** `org.osgi.service.servlet` 1.2 * re-export packages specified in OSGi CMPN R7 140 "Http Whiteboard Specification" -** `org.osgi.service.http.context` 1.1 -** `org.osgi.service.http.runtime` 1.1 -** `org.osgi.service.http.runtime.dto` 1.1 -** `org.osgi.service.http.whiteboard` 1.1 -** `org.osgi.service.http.whiteboard.annotations` 1.1 -** `org.osgi.service.http.whiteboard.propertytypes` 1.1 +** `org.osgi.service.servlet.context` 1.1 +** `org.osgi.service.servlet.runtime` 1.1 +** `org.osgi.service.servlet.runtime.dto` 1.1 +** `org.osgi.service.servlet.whiteboard` 1.1 +** `org.osgi.service.servlet.whiteboard.annotations` 1.1 +** `org.osgi.service.servlet.whiteboard.propertytypes` 1.1 * provide additional interfaces (like `org.ops4j.pax.web.service.WebContainer`) extending standard specification * provide some utilities used throughout PAX WEB (`org.ops4j.pax.web.utils` package) @@ -295,19 +295,19 @@ Since OSGi CMPN R6, Http Whiteboard is an official specification and Pax Web (wh CMPN R7 Http Whiteboard Specification allows registration (as OSGi services) of the following services: -* 140.4 Registering Servlets: `javax.servlet.Servlet` services +* 140.4 Registering Servlets: `jakarta.servlet.Servlet` services * 140.5 Registering Servlet Filters: -** `javax.servlet.Filter` services -** `org.osgi.service.http.whiteboard.Preprocessor` services handled before security processing +** `jakarta.servlet.Filter` services +** `org.osgi.service.servlet.whiteboard.Preprocessor` services handled before security processing * 140.6 Registering Resources: any objects with `osgi.http.whiteboard.resource.pattern` and `osgi.http.whiteboard.resource.prefix` service properties. Actual service is irrelevant * 140.7 Registering Listeners: services with these subinterfaces of `java.util.EventListener`: -** `javax.servlet.ServletContextListener` -** `javax.servlet.ServletContextAttributeListener` -** `javax.servlet.ServletRequestListener` -** `javax.servlet.ServletRequestAttributeListener` -** `javax.servlet.http.HttpSessionListener` -** `javax.servlet.http.HttpSessionAttributeListener` -** `javax.servlet.http.HttpSessionIdListener` +** `jakarta.servlet.ServletContextListener` +** `jakarta.servlet.ServletContextAttributeListener` +** `jakarta.servlet.ServletRequestListener` +** `jakarta.servlet.ServletRequestAttributeListener` +** `jakarta.servlet.http.HttpSessionListener` +** `jakarta.servlet.http.HttpSessionAttributeListener` +** `jakarta.servlet.http.HttpSessionIdListener` When registering the above servives, all additional and required information should be specified as OSGi service properties and/or Java annotations on the services. Annotations where specified only in R7 Whiteboard specification. Version R6 specified only service registration properties. @@ -319,11 +319,11 @@ This may be called _explicit whiteboard approach_ (where registration parameters === Context -Java Servlet API specification defines `javax.servlet.ServletContext` interface which roughly means a distinguished namespace (with _context path_) where servlets, filters and other _web elements_ may be specified. +Java Servlet API specification defines `jakarta.servlet.ServletContext` interface which roughly means a distinguished namespace (with _context path_) where servlets, filters and other _web elements_ may be specified. -OSGi CMPN Http Service specification defines `org.osgi.service.http.HttpContext` interface that should _influence_ the `javax.servlet.ServletContext` associated with the servlets (and resources) being registered. +OSGi CMPN Http Service specification defines `org.ops4j.pax.web.service.http.HttpContext` interface that should _influence_ the `jakarta.servlet.ServletContext` associated with the servlets (and resources) being registered. -OSGi CMPN Whiteboard specification defines `org.osgi.service.http.context.ServletContextHelper` interface that plays the same role as the above `HttpContext`, but which is dedicated for Whiteboard specification. +OSGi CMPN Whiteboard specification defines `org.osgi.service.servlet.context.ServletContextHelper` interface that plays the same role as the above `HttpContext`, but which is dedicated for Whiteboard specification. This `ServletContextHelper` is explicitly associated with _context path_ (using `osgi.http.whiteboard.context.path` service registration property) - unlike `HttpContext` which doesn't have a _context path_. OSGi CMPN HTTP Service specification (102.2 Registering servlets) mentions: @@ -333,7 +333,7 @@ OSGi CMPN HTTP Service specification (102.2 Registering servlets) mentions: [...]. Thus, Servlet objects registered with the same HttpContext object must also share the same ServletContext object. ---- -Without actually specifying what _the same_ means. `felix.http` implements `org.osgi.service.http.HttpService.createDefaultHttpContext()` by returning _new_ instance of `org.apache.felix.http.base.internal.service.DefaultHttpContext` on each call... +Without actually specifying what _the same_ means. `felix.http` implements `org.ops4j.pax.web.service.http.HttpService.createDefaultHttpContext()` by returning _new_ instance of `org.apache.felix.http.base.internal.service.DefaultHttpContext` on each call... OSGi CMPN Whiteboard specification (140.10 Integration with Http Service contexts) says: diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConfig.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConfig.java index 28d8e5987f..377607d729 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConfig.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConfig.java @@ -17,7 +17,7 @@ import java.security.cert.CertStoreParameters; import javax.net.ssl.SSLContext; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; /** *

Dedicated interface with constants related to configuration. Other constants reside @@ -65,28 +65,28 @@ public interface PaxWebConfig { * This property specifies the port used for servlets and resources accessible via HTTP. * The default value for this property is {@code 80} according to specification, but we'll use {@code 8080}. */ - String PID_CFG_HTTP_PORT = "org.osgi.service.http.port"; + String PID_CFG_HTTP_PORT = "org.osgi.service.servlet.port"; /** * This property specifies the port used for servlets and resources accessible via HTTPS. * The default value for this property is {@code 443} according to specificaton, but we'll use {@code 8443}. */ - String PID_CFG_HTTP_PORT_SECURE = "org.osgi.service.http.port.secure"; + String PID_CFG_HTTP_PORT_SECURE = "org.osgi.service.servlet.port.secure"; /** Should the default non-secure port be enabled? */ - String PID_CFG_HTTP_ENABLED = "org.osgi.service.http.enabled"; + String PID_CFG_HTTP_ENABLED = "org.osgi.service.servlet.enabled"; /** Should the default secure port be enabled? */ - String PID_CFG_HTTP_SECURE_ENABLED = "org.osgi.service.http.secure.enabled"; + String PID_CFG_HTTP_SECURE_ENABLED = "org.osgi.service.servlet.secure.enabled"; /** Comma-separated list of addresses to bind listeners/connectors to. Defaults to {@code 0.0.0.0} */ String PID_CFG_LISTENING_ADDRESSES = "org.ops4j.pax.web.listening.addresses"; /** Name to use as default (non-secure) connector, defaults to {@code default}. */ - String PID_CFG_HTTP_CONNECTOR_NAME = "org.osgi.service.http.connector.name"; + String PID_CFG_HTTP_CONNECTOR_NAME = "org.osgi.service.servlet.connector.name"; /** Name to use as secure connector, defaults to {@code secureDefault}. */ - String PID_CFG_HTTP_SECURE_CONNECTOR_NAME = "org.osgi.service.http.secure.connector.name"; + String PID_CFG_HTTP_SECURE_CONNECTOR_NAME = "org.osgi.service.servlet.secure.connector.name"; /** * Jetty: {@code org.eclipse.jetty.server.AbstractConnector#setIdleTimeout(long)} @@ -119,7 +119,7 @@ public interface PaxWebConfig { /** * Jetty: adds {@code org.eclipse.jetty.server.ForwardedRequestCustomizer} to {@code HttpConfiguration} */ - String PID_CFG_HTTP_CHECK_FORWARDED_HEADERS = "org.osgi.service.http.checkForwardedHeaders"; + String PID_CFG_HTTP_CHECK_FORWARDED_HEADERS = "org.osgi.service.servlet.checkForwardedHeaders"; /** * Comma-separated list of virtual hosts to set on every deployed context if the context itself @@ -162,7 +162,7 @@ public interface PaxWebConfig { String BUNDLE_CONTEXT_PROPERTY_WAR_EXTENDER_JARS_TO_SCAN = "org.ops4j.pax.web.extender.war.jarsToScan"; /** - *

Defines the type of TCCL that should be set for service methods (like {@link javax.servlet.Servlet#service}). + *

Defines the type of TCCL that should be set for service methods (like {@link jakarta.servlet.Servlet#service}). * It can take two values:

    *
  • {@code servlet} (the default, assumed value) - {@link ServletContext#getClassLoader()} returns * only the bundle's class loader for given servlet/filter, but TCCL is set to servlet context's classloader
  • diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConstants.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConstants.java index 3f54de204b..75a6296828 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConstants.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/PaxWebConstants.java @@ -17,10 +17,10 @@ package org.ops4j.pax.web.service; import java.net.JarURLConnection; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.ops4j.pax.web.service.whiteboard.ContextMapping; -import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; +import org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants; /** *

    Different constants used across Pax Web but not related to configuration that may be specified using @@ -28,7 +28,7 @@ * {@link PaxWebConfig}.

    *

    Constants names use the following prefixes:

      *
    • {@code SERVICE_PROPERTY_} - for names of OSGi service registration properties
    • - *
    • {@code INIT_PARAM_} - for legacy init parameters passed to {@link org.osgi.service.http.HttpService} + *
    • {@code INIT_PARAM_} - for legacy init parameters passed to {@link org.ops4j.pax.web.service.http.HttpService} * registration methods that are handled in special way by Pax Web.
    • *
    • {@code CONTEXT_PARAM_} - for {@link ServletContext} attributes set by Pax Web.
    • *
    • {@code DEFAULT_} - for miscellaneous default values (default VHost, default name, default context, @@ -45,11 +45,11 @@ public interface PaxWebConstants { /** Actual OSGi Http Service will be registered under these {@code objectClass} names. */ String[] HTTPSERVICE_REGISTRATION_NAMES = { - org.osgi.service.http.HttpService.class.getName(), + org.ops4j.pax.web.service.http.HttpService.class.getName(), org.ops4j.pax.web.service.WebContainer.class.getName() }; - /** Default name for context (e.g., {@link org.osgi.service.http.context.ServletContextHelper}) */ + /** Default name for context (e.g., {@link org.osgi.service.servlet.context.ServletContextHelper}) */ String DEFAULT_CONTEXT_NAME = HttpWhiteboardConstants.HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME; /** Name for default shared contexts - Pax Web specific */ @@ -64,26 +64,26 @@ public interface PaxWebConstants { /** The only supported JSP servlet class name */ String DEFAULT_JSP_SERVLET_CLASS = "org.ops4j.pax.web.jsp.JspServlet"; - /** The only supported {@link javax.servlet.ServletContainerInitializer} class that configures JSP engine */ + /** The only supported {@link jakarta.servlet.ServletContainerInitializer} class that configures JSP engine */ String DEFAULT_JSP_SCI_CLASS = "org.ops4j.pax.web.jsp.JasperInitializer"; /** - * The only supported {@link javax.servlet.ServletContainerInitializer} class that configures WebSocket + * The only supported {@link jakarta.servlet.ServletContainerInitializer} class that configures WebSocket * container for Jetty */ String DEFAULT_WEBSOCKET_JETTY_SCI_CLASS = "org.eclipse.jetty.websocket.javax.server.config.JavaxWebSocketServletContainerInitializer"; /** - * The only supported {@link javax.servlet.ServletContainerInitializer} class that configures WebSocket + * The only supported {@link jakarta.servlet.ServletContainerInitializer} class that configures WebSocket * container for Tomcat */ String DEFAULT_WEBSOCKET_TOMCAT_SCI_CLASS = "org.apache.tomcat.websocket.server.WsSci"; /** - * The only supported {@link javax.servlet.ServletContainerInitializer} class that configures WebSocket + * The only supported {@link jakarta.servlet.ServletContainerInitializer} class that configures WebSocket * container for Undertow */ String DEFAULT_WEBSOCKET_UNDERTOW_SCI_CLASS = "org.ops4j.pax.web.service.undertow.websocket.internal.WebSocketsInitializer"; /** - * The only supported {@link javax.servlet.ServletContainerInitializer} for generic configuration of + * The only supported {@link jakarta.servlet.ServletContainerInitializer} for generic configuration of * WebSocket container */ String DEFAULT_WEBSOCKET_SCI_CLASS = "org.ops4j.pax.web.websocket.internal.PaxWebWebSocketsServletContainerInitializer"; @@ -128,8 +128,8 @@ public interface PaxWebConstants { *

      Pax Web specific service property used when registering:

        *
      • {@link org.ops4j.pax.web.service.whiteboard.ServletContextHelperMapping}
      • *
      • {@link org.ops4j.pax.web.service.whiteboard.HttpContextMapping}
      • - *
      • {@link org.osgi.service.http.context.ServletContextHelper}
      • - *
      • {@link org.osgi.service.http.HttpContext}
      • + *
      • {@link org.osgi.service.servlet.context.ServletContextHelper}
      • + *
      • {@link org.ops4j.pax.web.service.http.HttpContext}
      • *
      * services to indicate virtual hosts with which this context should be associated (though for the two * Pax Web specific mappings, {@link ContextMapping#getVirtualHosts()} takes precedence).

      @@ -141,7 +141,7 @@ public interface PaxWebConstants { String SERVICE_PROPERTY_VIRTUAL_HOSTS_LEGACY = "httpContext.virtualhosts"; /** *

      Improved name for the service registration property to configure virtual hosts of the context - * ({@link org.osgi.service.http.context.ServletContextHelper}, {@link org.osgi.service.http.HttpContext}, etc.).

      + * ({@link org.osgi.service.servlet.context.ServletContextHelper}, {@link org.ops4j.pax.web.service.http.HttpContext}, etc.).

      *

      See http://www.eclipse.org/jetty/documentation/jetty-9/index.html#configuring-virtual-hosts

      */ String SERVICE_PROPERTY_VIRTUAL_HOSTS = "org.ops4j.pax.web.http.whiteboard.virtualhosts"; @@ -150,8 +150,8 @@ public interface PaxWebConstants { *

      Pax Web specific service property used when registering:

        *
      • {@link org.ops4j.pax.web.service.whiteboard.ServletContextHelperMapping}
      • *
      • {@link org.ops4j.pax.web.service.whiteboard.HttpContextMapping}
      • - *
      • {@link org.osgi.service.http.context.ServletContextHelper}
      • - *
      • {@link org.osgi.service.http.HttpContext}
      • + *
      • {@link org.osgi.service.servlet.context.ServletContextHelper}
      • + *
      • {@link org.ops4j.pax.web.service.http.HttpContext}
      • *
      * services to indicate connector ids through which this context should be associated (though for the two * Pax Web specific mappings, {@link ContextMapping#getConnectors()} takes precedence).

      @@ -163,21 +163,21 @@ public interface PaxWebConstants { String SERVICE_PROPERTY_CONNECTORS_LEGACY = "httpContext.connectors"; /** *

      Improved name for the service registration property to configure connectors of the context - * ({@link org.osgi.service.http.context.ServletContextHelper}, {@link org.osgi.service.http.HttpContext}, etc.).

      + * ({@link org.osgi.service.servlet.context.ServletContextHelper}, {@link org.ops4j.pax.web.service.http.HttpContext}, etc.).

      *

      See http://www.eclipse.org/jetty/documentation/jetty-9/index.html#configuring-virtual-hosts

      */ String SERVICE_PROPERTY_CONNECTORS = "org.ops4j.pax.web.http.whiteboard.connectors"; /** * Legacy service property for context ID. - * @deprecated Use {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_CONTEXT_NAME} + * @deprecated Use {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_CONTEXT_NAME} */ @Deprecated String SERVICE_PROPERTY_HTTP_CONTEXT_ID = "httpContext.id"; /** - * Legacy property name for a legacy "shared" flag for {@link org.osgi.service.http.HttpContext} services. - * @deprecated User {@link org.osgi.service.http.context.ServletContextHelper} services which are "shared" + * Legacy property name for a legacy "shared" flag for {@link org.ops4j.pax.web.service.http.HttpContext} services. + * @deprecated User {@link org.osgi.service.servlet.context.ServletContextHelper} services which are "shared" * by default */ @Deprecated @@ -185,7 +185,7 @@ public interface PaxWebConstants { /** * Legacy context path. - * @deprecated Use {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_CONTEXT_PATH} + * @deprecated Use {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_CONTEXT_PATH} */ @Deprecated String SERVICE_PROPERTY_HTTP_CONTEXT_PATH = "httpContext.path"; @@ -248,11 +248,11 @@ public interface PaxWebConstants { /** * Filter init param name for specifying a filter-mapping dispatch behaviour Must be a comma delimited string of: *
        - *
      • {@link javax.servlet.DispatcherType#REQUEST}
      • - *
      • {@link javax.servlet.DispatcherType#FORWARD}
      • - *
      • {@link javax.servlet.DispatcherType#INCLUDE}
      • - *
      • {@link javax.servlet.DispatcherType#ERROR}
      • - *
      • {@link javax.servlet.DispatcherType#ASYNC}
      • + *
      • {@link jakarta.servlet.DispatcherType#REQUEST}
      • + *
      • {@link jakarta.servlet.DispatcherType#FORWARD}
      • + *
      • {@link jakarta.servlet.DispatcherType#INCLUDE}
      • + *
      • {@link jakarta.servlet.DispatcherType#ERROR}
      • + *
      • {@link jakarta.servlet.DispatcherType#ASYNC}
      • *
      *

      * values are not case sensitive. diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainer.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainer.java index c0d7782977..cdd653dc83 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainer.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainer.java @@ -19,19 +19,19 @@ import java.util.Dictionary; import java.util.EventListener; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.MultipartConfigElement; -import javax.servlet.Servlet; -import javax.servlet.ServletContainerInitializer; -import javax.servlet.ServletException; -import javax.servlet.SessionCookieConfig; -import javax.servlet.descriptor.JspPropertyGroupDescriptor; -import javax.servlet.descriptor.TaglibDescriptor; - +import jakarta.servlet.Filter; +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletContainerInitializer; +import jakarta.servlet.ServletException; +import jakarta.servlet.SessionCookieConfig; +import jakarta.servlet.descriptor.JspPropertyGroupDescriptor; +import jakarta.servlet.descriptor.TaglibDescriptor; + +import org.ops4j.pax.web.service.http.HttpContext; +import org.ops4j.pax.web.service.http.HttpService; +import org.ops4j.pax.web.service.http.NamespaceException; import org.ops4j.pax.web.service.views.PaxWebContainerView; -import org.osgi.service.http.HttpContext; -import org.osgi.service.http.HttpService; -import org.osgi.service.http.NamespaceException; /** *

      @@ -59,7 +59,7 @@ *

      * All registration methods allow passing an instance of {@link HttpContext} * from original Http Service specification to indicate particular - * context ({@link javax.servlet.ServletContext} from Servlet API) + * context ({@link jakarta.servlet.ServletContext} from Servlet API) * where given web component should be registered. This means that this web * container represents entire Java HTTP/Servlet container which * organizes web elements (like servlets) in contexts or simply web @@ -133,7 +133,7 @@ default T adapt(Class type) { *

    • standard (Whiteboard) * {@code osgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.name=name)} * service registration property even if this property is designed to - * reference {@link org.osgi.service.http.context.ServletContextHelper} + * reference {@link org.osgi.service.servlet.context.ServletContextHelper} * instances
    • *
    • legacy (Pax Web specific) {@code httpContext.id=name} service * registration property
    • @@ -151,7 +151,7 @@ default T adapt(Class type) { * *

      * In OSGi CMPN Whiteboard implementation there's no special API to create - * instances of {@link org.osgi.service.http.context.ServletContextHelper} + * instances of {@link org.osgi.service.servlet.context.ServletContextHelper} * instances. *

      * @@ -578,14 +578,14 @@ void registerFilter(Class filterClass, String filterName, Stri /** *

      Registers an event listener. Depending on the listener type, the listener will be notified on different life * cycle events. The following listeners are supported:

        - *
      • {@link javax.servlet.http.HttpSessionActivationListener}
      • - *
      • {@link javax.servlet.http.HttpSessionAttributeListener}
      • - *
      • {@link javax.servlet.http.HttpSessionBindingListener}
      • - *
      • {@link javax.servlet.http.HttpSessionListener}
      • - *
      • {@link javax.servlet.ServletContextListener}
      • - *
      • {@link javax.servlet.ServletContextAttributeListener}
      • - *
      • {@link javax.servlet.ServletRequestListener}
      • - *
      • {@link javax.servlet.ServletRequestAttributeListener}
      • + *
      • {@link jakarta.servlet.http.HttpSessionActivationListener}
      • + *
      • {@link jakarta.servlet.http.HttpSessionAttributeListener}
      • + *
      • {@link jakarta.servlet.http.HttpSessionBindingListener}
      • + *
      • {@link jakarta.servlet.http.HttpSessionListener}
      • + *
      • {@link jakarta.servlet.ServletContextListener}
      • + *
      • {@link jakarta.servlet.ServletContextAttributeListener}
      • + *
      • {@link jakarta.servlet.ServletRequestListener}
      • + *
      • {@link jakarta.servlet.ServletRequestAttributeListener}
      • *
      • *
      * Check out Servlet specification for details on what type of event the registered listener will be notified.

      diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerContext.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerContext.java index ceb6f14793..29fdb19e14 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerContext.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/WebContainerContext.java @@ -16,32 +16,32 @@ package org.ops4j.pax.web.service; import java.util.Set; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.ops4j.pax.web.service.http.HttpContext; import org.ops4j.pax.web.service.whiteboard.ContextRelated; import org.osgi.framework.Bundle; -import org.osgi.service.http.HttpContext; -import org.osgi.service.http.context.ServletContextHelper; +import org.osgi.service.servlet.context.ServletContextHelper; /** *

      {@link HttpContext} extension that adds:

        *
      • identity (String ID) to {@link HttpContext} (knowing that single bundle using such context * is part of the identity)
      • - *
      • missing resource-access method matching {@link javax.servlet.ServletContext#getResourcePaths(String)} + *
      • missing resource-access method matching {@link jakarta.servlet.ServletContext#getResourcePaths(String)} * method.
      • *
      • shared flag
      • *

      * *

      All methods returning a context in {@link WebContainer} extension of - * {@link org.osgi.service.http.HttpService} return implementations of this interface.

      + * {@link org.ops4j.pax.web.service.http.HttpService} return implementations of this interface.

      * *

      No extension of the original {@link HttpContext} should specify such things as context path, virtual hosts * or parameters - these (to match Whiteboard specification) should be specified using service registration * paremeters or (legacy Pax Web method) in {@code org.ops4j.pax.web.service.whiteboard.HttpContextMapping} service * or (legacy and not recommended) {@code org.ops4j.pax.web.service.whiteboard.ServletContextHelperMapping}.

      * - *

      Internally, Pax Web will wrap Whiteboard's {@link org.osgi.service.http.context.ServletContextHelper} instances + *

      Internally, Pax Web will wrap Whiteboard's {@link org.osgi.service.servlet.context.ServletContextHelper} instances * in some implementation of {@link WebContainerContext} interface.

      * * @author Alin Dreghiciu (adreghiciu@gmail.com) @@ -51,10 +51,10 @@ public interface WebContainerContext extends HttpContext { /** *

      Complement {@link HttpContext#getResource(String)} (that matches - * {@link javax.servlet.ServletContext#getResource(String)}), so we have a method matching - * {@link javax.servlet.ServletContext#getResourcePaths(String)}.

      + * {@link jakarta.servlet.ServletContext#getResource(String)}), so we have a method matching + * {@link jakarta.servlet.ServletContext#getResourcePaths(String)}.

      * - *

      from {@link javax.servlet.ServletContext} javadoc: Returns a set of all the paths (String objects) + *

      from {@link jakarta.servlet.ServletContext} javadoc: Returns a set of all the paths (String objects) * to entries within the web application whose longest sub-path matches the supplied path argument. * A specified path of "/" indicates the root of the web application.

      * @@ -68,18 +68,18 @@ public interface WebContainerContext extends HttpContext { * {@code /WEB-INF/lib/*.jar!/META-INF/resources/} if the bundle is WAB.

      * * @param path the path name for which to return resource paths. Just as in - * {@link javax.servlet.ServletContext#getResourcePaths(String)}, the path must start with {@code /} + * {@link jakarta.servlet.ServletContext#getResourcePaths(String)}, the path must start with {@code /} * @return a set of the resource paths (String objects) or null if no resource paths could be found or if * the caller does not have the appropriate permissions. */ Set getResourcePaths(String path); /** - *

      Method matching {@link javax.servlet.ServletContext#getRealPath(String)} and - * {@link org.osgi.service.http.context.ServletContextHelper#getRealPath(String)}, but not available in + *

      Method matching {@link jakarta.servlet.ServletContext#getRealPath(String)} and + * {@link org.osgi.service.servlet.context.ServletContextHelper#getRealPath(String)}, but not available in * original {@link HttpContext}.

      * - *

      As in Javadoc for {@link javax.servlet.ServletContext#getRealPath(String)}: + *

      As in Javadoc for {@link jakarta.servlet.ServletContext#getRealPath(String)}: * Resources inside the /META-INF/resources directories of JAR files bundled in the application's * /WEB-INF/lib directory must be considered only if the container has unpacked them from their containing * JAR file, in which case the path to the unpacked location must be returned. @@ -94,7 +94,7 @@ default String getRealPath(String path) { } /** - * Method that backports {@link org.osgi.service.http.context.ServletContextHelper#finishSecurity} + * Method that backports {@link org.osgi.service.servlet.context.ServletContextHelper#finishSecurity} * into old {@link HttpContext} * * @param request @@ -116,10 +116,10 @@ default String getRealPath(String path) { *

    * *

    There's security concern related to String identification of context - both for - * {@link org.osgi.service.http.HttpService#registerServlet} and whiteboard approach. If (as Pax Web allows) + * {@link org.ops4j.pax.web.service.http.HttpService#registerServlet} and whiteboard approach. If (as Pax Web allows) * shared context is used, there should be no way of accessing resources from one bundle by another * bundle. Whiteboard specification is more clear about it - resources are loaded from the bundle registering - * (publishing) {@link org.osgi.service.http.context.ServletContextHelper} service and there's assumed + * (publishing) {@link org.osgi.service.servlet.context.ServletContextHelper} service and there's assumed * sharing of the context between bundles. That's why user chosing {@link MultiBundleWebContainerContext} * has to be aware of opening an access to all bundles sharing such context.

    * @@ -131,7 +131,7 @@ default String getRealPath(String path) { *

    Should this context (as defined in "102 Http Service" specification, not in "140 Whiteboard Service" * specification) be allowed to be used by different bundles?

    * - *

    In Whiteboard Service scenario (to wrap {@link org.osgi.service.http.context.ServletContextHelper}) + *

    In Whiteboard Service scenario (to wrap {@link org.osgi.service.servlet.context.ServletContextHelper}) * the context should be shared by default and there's no real way to make a context not shared.

    * *

    In Http Service scenario, but default, a context is not shared. It means that if a web element @@ -154,7 +154,7 @@ default String getRealPath(String path) { */ enum DefaultContextIds { /** - * Used for {@link org.osgi.service.http.HttpService#createDefaultHttpContext()} + * Used for {@link org.ops4j.pax.web.service.http.HttpService#createDefaultHttpContext()} */ DEFAULT(PaxWebConstants.DEFAULT_CONTEXT_NAME), diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpContext.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpContext.java new file mode 100644 index 0000000000..18184b5255 --- /dev/null +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpContext.java @@ -0,0 +1,185 @@ +/* + * Copyright 2023 OPS4J. + * + * Licensed 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.ops4j.pax.web.service.http; + +import java.io.IOException; +import java.net.URL; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +/** + * Context for HTTP Requests. + * + *

    + * This service defines methods that the Http Service may call to get + * information for a request. + * + *

    + * Servlets may be associated with an {@code HttpContext} service. Servlets that + * are associated using the same {@code HttpContext} object will share the same + * {@code ServletContext} object. + * + *

    + * If no {@code HttpContext} service is associated, a default + * {@code HttpContext} is used. The behavior of the methods on the default + * {@code HttpContext} is defined as follows: + *

      + *
    • {@code getMimeType} - Does not define any customized MIME types for the + * {@code Content-Type} header in the response, and always returns {@code null}. + *
    • + *
    • {@code handleSecurity} - Performs implementation-defined authentication + * on the request.
    • + *
    • {@code getResource} - Assumes the named resource is in the bundle of the + * servlet service. This method calls the servlet bundle's + * {@code Bundle.getResource} method, and returns the appropriate URL to access + * the resource. On a Java runtime environment that supports permissions, the + * Http Service needs to be granted + * {@code org.osgi.framework.AdminPermission[*,RESOURCE]}.
    • + *
    + * + * @author $Id: ab5459d16e836e60dca639d9e073f95ebccad271 $ + */ +public interface HttpContext { + + /** + * {@code HttpServletRequest} attribute specifying the name of the + * authenticated user. The value of the attribute can be retrieved by + * {@code HttpServletRequest.getRemoteUser}. This attribute name is + * {@code org.osgi.service.http.authentication.remote.user}. + * + * @since 1.1 + */ + String REMOTE_USER = "org.osgi.service.http.authentication.remote.user"; + + /** + * {@code HttpServletRequest} attribute specifying the scheme used in + * authentication. The value of the attribute can be retrieved by + * {@code HttpServletRequest.getAuthType}. This attribute name is + * {@code org.osgi.service.http.authentication.type}. + * + * @since 1.1 + */ + String AUTHENTICATION_TYPE = "org.osgi.service.http.authentication.type"; + + /** + * {@code HttpServletRequest} attribute specifying the {@code Authorization} + * object obtained from the {@code org.osgi.service.useradmin.UserAdmin} + * service. The value of the attribute can be retrieved by + * {@code HttpServletRequest.getAttribute(HttpContext.AUTHORIZATION)}. This + * attribute name is {@code org.osgi.service.useradmin.authorization}. + * + * @since 1.1 + */ + String AUTHORIZATION = "org.osgi.service.useradmin.authorization"; + + /** + * Handles security for the specified request. + * + *

    + * The Http Service calls this method prior to servicing the specified + * request. This method controls whether the request is processed in the + * normal manner or an error is returned. + * + *

    + * If the request requires authentication and the Authorization header in + * the request is missing or not acceptable, then this method should set the + * WWW-Authenticate header in the response object, set the status in the + * response object to Unauthorized(401) and return {@code false}. See also + * RFC 2617: HTTP Authentication: Basic and Digest Access Authentication + * (available at RFC 2617). + * + *

    + * If the request requires a secure connection and the {@code getScheme} + * method in the request does not return 'https' or some other acceptable + * secure protocol, then this method should set the status in the response + * object to Forbidden(403) and return {@code false}. + * + *

    + * When this method returns {@code false}, the Http Service will send the + * response back to the client, thereby completing the request. When this + * method returns {@code true}, the Http Service will proceed with servicing + * the request. + * + *

    + * If the specified request has been authenticated, this method must set the + * {@link #AUTHENTICATION_TYPE} request attribute to the type of + * authentication used, and the {@link #REMOTE_USER} request attribute to + * the remote user (request attributes are set using the + * {@code setAttribute} method on the request). If this method does not + * perform any authentication, it must not set these attributes. + * + *

    + * If the authenticated user is also authorized to access certain resources, + * this method must set the {@link #AUTHORIZATION} request attribute to the + * {@code Authorization} object obtained from the + * {@code org.osgi.service.useradmin.UserAdmin} service. + * + *

    + * The servlet responsible for servicing the specified request determines + * the authentication type and remote user by calling the + * {@code getAuthType} and {@code getRemoteUser} methods, respectively, on + * the request. + * + * @param request The HTTP request. + * @param response The HTTP response. + * @return {@code true} if the request should be serviced, {@code false} if + * the request should not be serviced and Http Service will send the + * response back to the client. + * @throws java.io.IOException may be thrown by this method. If this occurs, + * the Http Service will terminate the request and close the socket. + */ + boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException; + + /** + * Maps a resource name to a URL. + * + *

    + * Called by the Http Service to map a resource name to a URL. For servlet + * registrations, Http Service will call this method to support the + * {@code ServletContext} methods {@code getResource} and + * {@code getResourceAsStream}. For resource registrations, Http Service + * will call this method to locate the named resource. The context can + * control from where resources come. For example, the resource can be + * mapped to a file in the bundle's persistent storage area via + * {@code bundleContext.getDataFile(name).toURL()} or to a resource in the + * context's bundle via {@code getClass().getResource(name)} + * + * @param name the name of the requested resource + * @return URL that Http Service can use to read the resource or + * {@code null} if the resource does not exist. + */ + URL getResource(String name); + + /** + * Maps a name to a MIME type. + * + *

    + * Called by the Http Service to determine the MIME type for the specified + * name. For servlets, the Http Service will call this method to support the + * {@code ServletContext} method {@code getMimeType}. For resources, the + * Http Service will call this method to determine the MIME type for the + * {@code Content-Type} header in the response. + * + * @param name The name for which to determine the MIME type. + * @return The MIME type (e.g. text/html) of the specified name or + * {@code null} to indicate that the Http Service should determine + * the MIME type itself. + */ + String getMimeType(String name); + +} diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpService.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpService.java new file mode 100644 index 0000000000..c0d8460846 --- /dev/null +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/HttpService.java @@ -0,0 +1,175 @@ +/* + * Copyright 2023 OPS4J. + * + * Licensed 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.ops4j.pax.web.service.http; + +import java.util.Dictionary; + +import jakarta.servlet.Servlet; +import jakarta.servlet.ServletException; + +/** + * The Http Service allows other bundles in the OSGi environment to dynamically + * register resources and servlets into the URI namespace of Http Service. A + * bundle may later unregister its resources or servlets. + * + * @author $Id: 4ed5578fbcfcedc725a6136b6ac4059f961bbf4c $ + * @noimplement + * @see HttpContext + */ +public interface HttpService { + + /** + * Registers a servlet into the URI namespace. + * + *

    + * The alias is the name in the URI namespace of the Http Service at which + * the registration will be mapped. + * + *

    + * An alias must begin with slash ('/') and must not end with slash ('/'), + * with the exception that an alias of the form "/" is used to + * denote the root alias. See the specification text for details on how HTTP + * requests are mapped to servlet and resource registrations. + * + *

    + * The Http Service will call the servlet's {@code init} method before + * returning. + * + *

    +     * httpService.registerServlet("/myservlet", servlet, initparams, context);
    +     * 
    + * + *

    + * Servlets registered with the same {@code HttpContext} object will share + * the same {@code ServletContext}. The Http Service will call the + * {@code context} argument to support the {@code ServletContext} methods + * {@code getResource},{@code getResourceAsStream} and {@code getMimeType}, + * and to handle security for requests. If the {@code context} argument is + * {@code null}, a default {@code HttpContext} object is used (see + * {@link #createDefaultHttpContext()}). + * + * @param alias name in the URI namespace at which the servlet is registered + * @param servlet the servlet object to register + * @param initparams initialization arguments for the servlet or + * {@code null} if there are none. This argument is used by the + * servlet's {@code ServletConfig} object. + * @param context the {@code HttpContext} object for the registered servlet, + * or {@code null} if a default {@code HttpContext} is to be created + * and used. + * @throws NamespaceException if the registration fails because the alias is + * already in use. + * @throws jakarta.servlet.ServletException if the servlet's {@code init} + * method throws an exception, or the given servlet object has + * already been registered at a different alias. + * @throws java.lang.IllegalArgumentException if any of the arguments are + * invalid + */ + void registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context) throws ServletException, NamespaceException; + + /** + * Registers resources into the URI namespace. + * + *

    + * The alias is the name in the URI namespace of the Http Service at which + * the registration will be mapped. An alias must begin with slash ('/') and + * must not end with slash ('/'), with the exception that an alias of the + * form "/" is used to denote the root alias. The name parameter + * must also not end with slash ('/') with the exception that a name of the + * form "/" is used to denote the root of the bundle. See the + * specification text for details on how HTTP requests are mapped to servlet + * and resource registrations. + *

    + * For example, suppose the resource name /tmp is registered to the alias + * /files. A request for /files/foo.txt will map to the resource name + * /tmp/foo.txt. + * + *

    +     * httpservice.registerResources("/files", "/tmp", context);
    +     * 
    + *

    + * The Http Service will call the {@code HttpContext} argument to map + * resource names to URLs and MIME types and to handle security for + * requests. If the {@code HttpContext} argument is {@code null}, a default + * {@code HttpContext} is used (see {@link #createDefaultHttpContext()}). + * + * @param alias name in the URI namespace at which the resources are + * registered + * @param name the base name of the resources that will be registered + * @param context the {@code HttpContext} object for the registered + * resources, or {@code null} if a default {@code HttpContext} is to + * be created and used. + * @throws NamespaceException if the registration fails because the alias is + * already in use. + * @throws java.lang.IllegalArgumentException if any of the parameters are + * invalid + */ + void registerResources(String alias, String name, HttpContext context) throws NamespaceException; + + /** + * Unregisters a previous registration done by {@code registerServlet} or + * {@code registerResources} methods. + * + *

    + * After this call, the registered alias in the URI name-space will no + * longer be available. If the registration was for a servlet, the Http + * Service must call the {@code destroy} method of the servlet before + * returning. + *

    + * If the bundle which performed the registration is stopped or otherwise + * "unget"s the Http Service without calling {@link #unregister(String)} + * then Http Service must automatically unregister the registration. + * However, if the registration was for a servlet, the {@code destroy} + * method of the servlet will not be called in this case since the bundle + * may be stopped. {@link #unregister(String)} must be explicitly called to + * cause the {@code destroy} method of the servlet to be called. This can be + * done in the {@code BundleActivator.stop} method of the bundle registering + * the servlet. + * + * @param alias name in the URI name-space of the registration to unregister + * @throws java.lang.IllegalArgumentException if there is no registration + * for the alias or the calling bundle was not the bundle which + * registered the alias. + */ + void unregister(String alias); + + /** + * Creates a default {@code HttpContext} for registering servlets or + * resources with the HttpService, a new {@code HttpContext} object is + * created each time this method is called. + * + *

    + * The behavior of the methods on the default {@code HttpContext} is defined + * as follows: + *

      + *
    • {@code getMimeType} - Does not define any customized MIME types for + * the Content-Type header in the response, and always returns {@code null}. + *
    • + *
    • {@code handleSecurity} - Performs implementation-defined + * authentication on the request.
    • + *
    • {@code getResource} - Assumes the named resource is in the context + * bundle; this method calls the context bundle's {@code Bundle.getResource} + * method, and returns the appropriate URL to access the resource. On a Java + * runtime environment that supports permissions, the Http Service needs to + * be granted {@code org.osgi.framework.AdminPermission[*,RESOURCE]}.
    • + *
    + * + * @return a default {@code HttpContext} object. + * @since 1.1 + */ + HttpContext createDefaultHttpContext(); + +} diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/NamespaceException.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/NamespaceException.java new file mode 100644 index 0000000000..591d9ba371 --- /dev/null +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/NamespaceException.java @@ -0,0 +1,91 @@ +/* + * Copyright 2023 OPS4J. + * + * Licensed 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.ops4j.pax.web.service.http; + +/** + * A NamespaceException is thrown to indicate an error with the caller's request + * to register a servlet or resources into the URI namespace of the Http + * Service. This exception indicates that the requested alias already is in use. + * + * @author $Id: 850fca5cacf0c39a585431f9abfd1ed163473848 $ + */ +public class NamespaceException extends Exception { + + private static final long serialVersionUID = 7235606031147877747L; + + /** + * Construct a {@code NamespaceException} object with a detail message. + * + * @param message the detail message + */ + public NamespaceException(String message) { + super(message); + } + + /** + * Construct a {@code NamespaceException} object with a detail message and a + * nested exception. + * + * @param message The detail message. + * @param cause The nested exception. + */ + public NamespaceException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Returns the nested exception. + * + *

    + * This method predates the general purpose exception chaining mechanism. + * The {@code getCause()} method is now the preferred means of obtaining + * this information. + * + * @return The result of calling {@code getCause()}. + */ + public Throwable getException() { + return getCause(); + } + + /** + * Returns the cause of this exception or {@code null} if no cause was set. + * + * @return The cause of this exception or {@code null} if no cause was set. + * @since 1.2 + */ + @Override + public Throwable getCause() { + return super.getCause(); + } + + /** + * Initializes the cause of this exception to the specified value. + * + * @param cause The cause of this exception. + * @return This exception. + * @throws IllegalArgumentException If the specified cause is this + * exception. + * @throws IllegalStateException If the cause of this exception has already + * been set. + * @since 1.2 + */ + @Override + public Throwable initCause(Throwable cause) { + return super.initCause(cause); + } + +} diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/package-info.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/package-info.java new file mode 100644 index 0000000000..a7b671b456 --- /dev/null +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/http/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright 2023 OPS4J. + * + * Licensed 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. + */ + +/** + *

    This package is for interfaces/classes that were available before OSGi CMPN 8.1 in + * Http Service Specification. + * This specification was removed from OSGi CMPN when switching from {@code javax} to {@code jakarta} + * namespace.

    + * + *

    Original package is {@code org.osgi.service.http}. There's no new equivalen of this package and users + * are encouraged to move to Jakarta Servlet Specificaiton (formerly known as + * Whiteboard specification).

    + */ +package org.ops4j.pax.web.service.http; diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/package-info.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/package-info.java index e80ef9a9fa..bc50c86a01 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/package-info.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/package-info.java @@ -16,7 +16,7 @@ /** * Main Pax Web API package providing:
      - *
    • extensions to {@link org.osgi.service.http.HttpService} from OSGi CMPN Http Service specification
    • + *
    • extensions to {@link org.ops4j.pax.web.service.http.HttpService} from OSGi CMPN Http Service specification
    • *
    • additional interfaces supporting OSGi CMPN Whiteboard specification
    • *
    */ diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextMapping.java index 4b7d10c1be..6bcc2cd71a 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextMapping.java @@ -16,14 +16,14 @@ package org.ops4j.pax.web.service.whiteboard; import java.util.Map; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; -import org.osgi.service.http.HttpContext; +import org.ops4j.pax.web.service.http.HttpContext; /** * Interface common for mappings related to context:
      - *
    • {@link org.osgi.service.http.HttpContext} for Http Service scenario
    • - *
    • {@link org.osgi.service.http.context.ServletContextHelper} for Whiteboard Service scenario
    • + *
    • {@link org.ops4j.pax.web.service.http.HttpContext} for Http Service scenario
    • + *
    • {@link org.osgi.service.servlet.context.ServletContextHelper} for Whiteboard Service scenario
    • *
    */ public interface ContextMapping { @@ -49,9 +49,9 @@ public interface ContextMapping { *

    When registering {@link HttpContext} directly, context path may be specified as * {@code httpContext.id} service registration property.

    * - *

    For complete picture, OSGi CMPN Whiteboard's {@link org.osgi.service.http.context.ServletContextHelper} + *

    For complete picture, OSGi CMPN Whiteboard's {@link org.osgi.service.servlet.context.ServletContextHelper} * may have context path specified using {@code osgi.http.whiteboard.context.name} service registration - * property or {@link org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardContext} annotation.

    + * property or {@link org.osgi.service.servlet.whiteboard.propertytypes.HttpWhiteboardContext} annotation.

    * * @return context path as in servlet context path; can be null */ diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextRelated.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextRelated.java index 473a7ba090..f1f4d1e37c 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextRelated.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ContextRelated.java @@ -21,50 +21,50 @@ *

    Super interface extended by all explicit whiteboard elements that can be registered by targeting * selected context.

    * - *

    Context is something different in {@link org.osgi.service.http.HttpService} case (it's represented - * by {@link org.osgi.service.http.HttpContext}) and in Whiteboard case (it's represented by - * {@link org.osgi.service.http.context.ServletContextHelper}). In both cases, eventually this context - * is actually backed by a real {@link javax.servlet.ServletContext} from Java Servlet API. Though it's not 1:1 + *

    Context is something different in {@link org.ops4j.pax.web.service.http.HttpService} case (it's represented + * by {@link org.ops4j.pax.web.service.http.HttpContext}) and in Whiteboard case (it's represented by + * {@link org.osgi.service.servlet.context.ServletContextHelper}). In both cases, eventually this context + * is actually backed by a real {@link jakarta.servlet.ServletContext} from Java Servlet API. Though it's not 1:1 * relation...

    * - *

    Both {@link org.osgi.service.http.HttpContext} and {@link org.osgi.service.http.context.ServletContextHelper} + *

    Both {@link org.ops4j.pax.web.service.http.HttpContext} and {@link org.osgi.service.servlet.context.ServletContextHelper} * do not specify a context path. It can be specified only by:

      *
    • (Pax Web legacy Whiteboard) {@code httpContext.path} service registration property when - * whiteboard-registering {@link org.osgi.service.http.HttpContext} service
    • + * whiteboard-registering {@link org.ops4j.pax.web.service.http.HttpContext} service *
    • (Pax Web legacy Whiteboard) whiteboard-registering a {@link HttpContextMapping} service with a path
    • *
    • (OSGI CMPN Whiteboard) - * {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_CONTEXT_PATH} service - * registration property when registering {@link org.osgi.service.http.context.ServletContextHelper} service + * {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_CONTEXT_PATH} service + * registration property when registering {@link org.osgi.service.servlet.context.ServletContextHelper} service *
    • *

    * - *

    The referenced context doesn't have to be unique wrt {@link javax.servlet.ServletContext}, there may be + *

    The referenced context doesn't have to be unique wrt {@link jakarta.servlet.ServletContext}, there may be * many contexts registered (as mentioned above) for given context path but using different name. * Servlet (or e.g., filter) may be associated with one (or more) - * {@link org.osgi.service.http.context.ServletContextHelper} (new Whiteboard) instance for given context path, + * {@link org.osgi.service.servlet.context.ServletContextHelper} (new Whiteboard) instance for given context path, * but actual (server specific) context (or web application) may be supported by different - * {@link org.osgi.service.http.context.ServletContextHelper} instances.

    + * {@link org.osgi.service.servlet.context.ServletContextHelper} instances.

    * *

    Pax Web will unify behavior of Http Service and Whiteboard style contexts (knowing that underneath - * there's actual, server-specific {@link javax.servlet.ServletContext}) and uniqueness will be checked by String ID - * (and bundle for bundle-scoped access). Additionally for old-style {@link org.osgi.service.http.HttpContext}, + * there's actual, server-specific {@link jakarta.servlet.ServletContext}) and uniqueness will be checked by String ID + * (and bundle for bundle-scoped access). Additionally for old-style {@link org.ops4j.pax.web.service.http.HttpContext}, * a shared flag will be checked to determine whether context may be used by different bundles. * Whiteboard (new-style) context is shared by default.

    * - *

    In {@link org.osgi.service.http.HttpService} case (no whiteboard), equality of - * {@link org.osgi.service.http.HttpContext} created by users is implied to be instance equality (same object). + *

    In {@link org.ops4j.pax.web.service.http.HttpService} case (no whiteboard), equality of + * {@link org.ops4j.pax.web.service.http.HttpContext} created by users is implied to be instance equality (same object). * Pax Web wraps such contexts and sets {@code custom} context ID in the wrapper.

    * *

    In non-whiteboard approach, servlets are always registered together with associated - * {@link org.osgi.service.http.HttpContext} when calling method like - * {@link org.osgi.service.http.HttpService#registerServlet}. User may also provide + * {@link org.ops4j.pax.web.service.http.HttpContext} when calling method like + * {@link org.ops4j.pax.web.service.http.HttpService#registerServlet}. User may also provide * {@link org.ops4j.pax.web.service.WebContainerContext} or {@link MultiBundleWebContainerContext} when registering * a servlet. That means (assuming Pax Web specific shared contexts) it's hard to reference common context * without using actual instance of the context, so such instance has to be shared through OSGi registry.

    * - *

    To support real sharing of {@link org.osgi.service.http.HttpContext} when using old - * {@link org.osgi.service.http.HttpService} methods, user first needs to register {@link HttpContextMapping} - * OSGi service or {@link org.osgi.service.http.HttpContext} service with {@code httpContext.id} registration + *

    To support real sharing of {@link org.ops4j.pax.web.service.http.HttpContext} when using old + * {@link org.ops4j.pax.web.service.http.HttpService} methods, user first needs to register {@link HttpContextMapping} + * OSGi service or {@link org.ops4j.pax.web.service.http.HttpContext} service with {@code httpContext.id} registration * property:

      *     // register pure HttpContext service
      *     props.put("httpContext.id", "my-context");
    @@ -83,17 +83,17 @@
      * 

    * *

    This trick is based on assumed identity of DefaultHttpContext, which is name+bundle and separates - * the identity from context behavior ({@link org.osgi.service.http.HttpContext#handleSecurity}), which + * the identity from context behavior ({@link org.ops4j.pax.web.service.http.HttpContext#handleSecurity}), which * should not be specified (or emphasized) in every registration.

    */ public interface ContextRelated { /** - *

    Get an LDAP-style filter to select {@link org.osgi.service.http.context.ServletContextHelper} instances + *

    Get an LDAP-style filter to select {@link org.osgi.service.servlet.context.ServletContextHelper} instances * to use when registering given element. This is generic, defined in Whiteboard * specification, way of associating the servlet (and filter, and listener, ...) with a context.

    * - *

    In generic scenario, when custom context ({@link org.osgi.service.http.context.ServletContextHelper} + *

    In generic scenario, when custom context ({@link org.osgi.service.servlet.context.ServletContextHelper} * in case of Whiteboard) is registered using:

     	 *     Dictionary props = new Hashtable<>();
     	 *     props.put("osgi.http.whiteboard.context.name", "my-context");
    @@ -109,7 +109,7 @@ public interface ContextRelated {
     	 * 

    Special Whiteboard-Http Service scenario (OSGi R7 CMPN 140.10 "Integration with Http Service Contexts") * mentions that a whiteboard element (excluding servlet, but let's not add such * restriction in Pax Web) may be associated with a context representing an old - * {@link org.osgi.service.http.HttpContext} using special context selection:

    +	 * {@link org.ops4j.pax.web.service.http.HttpContext} using special context selection:
     	 *     Dictionary props = new Hashtable<>();
     	 *     props.put("osgi.http.whiteboard.context.select", "(osgi.http.whiteboard.context.httpservice=*)");
     	 *     context.registerService(Servlet.class, ..., props);
    @@ -117,15 +117,15 @@ public interface ContextRelated {
     	 *
     	 * 

    This specification fragment says:

    * A Http Whiteboard service which should be registered with a Http Context from the Http Service can - * achieve this by targeting a {@link org.osgi.service.http.context.ServletContextHelper} with the + * achieve this by targeting a {@link org.osgi.service.servlet.context.ServletContextHelper} with the * registration property {@code osgi.http.whiteboard.context.httpservice}. *

    * *

    This seems a bit artificial:

      - *
    • We can't distinguish actual old-style context ({@link org.osgi.service.http.HttpContext})
    • + *
    • We can't distinguish actual old-style context ({@link org.ops4j.pax.web.service.http.HttpContext})
    • *
    • Specification requires the implementation to register special - * {@link org.osgi.service.http.context.ServletContextHelper} representing - * a {@link org.osgi.service.http.HttpContext}
    • + * {@link org.osgi.service.servlet.context.ServletContextHelper} representing + * a {@link org.ops4j.pax.web.service.http.HttpContext} *

    * * @return @@ -137,9 +137,9 @@ public interface ContextRelated { * of context association if no {@link #getContextSelectFilter()} is specified.

    * *

    In Whiteboard scenario, the context (actually, - * {@link org.osgi.service.http.context.ServletContextHelper}) is selected using an LDAP-like filter, see + * {@link org.osgi.service.servlet.context.ServletContextHelper}) is selected using an LDAP-like filter, see * {@link #getContextSelectFilter()}, which allows association with many servlet contexts. To simplify things, - * this method may just indicate single {@link org.osgi.service.http.context.ServletContextHelper} by name. + * this method may just indicate single {@link org.osgi.service.servlet.context.ServletContextHelper} by name. * It can be done using one of (in order of decreasing priority):

      *
    • standard (Whiteboard) * {@code osgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.name=name)} service registration diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ErrorPageMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ErrorPageMapping.java index d9d203fbc5..d2300daa7f 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ErrorPageMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ErrorPageMapping.java @@ -24,10 +24,10 @@ *

      This is Pax Web specific Whiteboard mapping approach, where all the details are * passed directly and not as service registration properties. The problem with CMPN Whitboard * specification is that error pages are not registered directly, but as service - * registration properties when registering a {@link javax.servlet.Servlet}. Also, such servlet is + * registration properties when registering a {@link jakarta.servlet.Servlet}. Also, such servlet is * not required to be associated with any URL pattern. Pax Web on the other hand matches the * {@code web.xml} model, where error page is a mapping from error codes/exception names - * to an URI (not a {@link javax.servlet.Servlet}). Thus in Pax Web we're forced to use artificial, + * to an URI (not a {@link jakarta.servlet.Servlet}). Thus in Pax Web we're forced to use artificial, * generated URI locations. With mapping approach, error mapping is registered together * with some servlet with can always be accessed directly (just as in {@code web.xml}.

      * @@ -46,8 +46,8 @@ public interface ErrorPageMapping extends ContextRelated { /** * URI mapping (must start with {@code /}) that'll be used to handle the exception/error. In case of standard * OSGi CMPN Whiteboard specification, the location is passed implicitly - the associated - * {@link javax.servlet.Servlet} being registered will handle the problem. In Pax Web Whiteboard mapping, - * actual servlet should be registered separately (by registering a {@link javax.servlet.Servlet} or + * {@link jakarta.servlet.Servlet} being registered will handle the problem. In Pax Web Whiteboard mapping, + * actual servlet should be registered separately (by registering a {@link jakarta.servlet.Servlet} or * {@link ServletMapping}). * @return */ diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/FilterMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/FilterMapping.java index 193e6e2411..cd68021ff3 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/FilterMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/FilterMapping.java @@ -16,8 +16,8 @@ package org.ops4j.pax.web.service.whiteboard; import java.util.Map; -import javax.servlet.DispatcherType; -import javax.servlet.Filter; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.Filter; /** *

      Filter mapping contains all the information required to register a {@link Filter}.

      @@ -48,7 +48,7 @@ public interface FilterMapping extends ContextRelated { *

      Get a name of the filter being registered. Matches {@code /} element from * {@code web.xml}.

      *

      In whiteboard method, this can be specified as:

        - *
      • {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_FILTER_NAME} + *
      • {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_FILTER_NAME} * property
      • *
      • {@code filter-name} service registration property (legacy Pax Web Whiteboard approach)
      • *

      diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/HttpContextMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/HttpContextMapping.java index 6c63a63eb2..067d797b76 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/HttpContextMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/HttpContextMapping.java @@ -16,7 +16,7 @@ package org.ops4j.pax.web.service.whiteboard; import org.osgi.framework.Bundle; -import org.osgi.service.http.HttpContext; +import org.ops4j.pax.web.service.http.HttpContext; /** *

      HttpContext mapping collects all the information required to register a {@link HttpContext} to @@ -52,7 +52,7 @@ public interface HttpContextMapping extends ContextMapping { /** *

      Get actual context being registered. This version accepts {@link Bundle} argument to reflect * recommendations from Whiteboard Service specification, where - * {@link org.osgi.service.http.context.ServletContextHelper} is suggested to be registered as + * {@link org.osgi.service.servlet.context.ServletContextHelper} is suggested to be registered as * {@link org.osgi.framework.ServiceFactory}.

      * * @param bundle diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ResourceMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ResourceMapping.java index 921e22acb9..9d58ad0248 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ResourceMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ResourceMapping.java @@ -15,16 +15,16 @@ */ package org.ops4j.pax.web.service.whiteboard; -import org.osgi.service.http.HttpContext; +import org.ops4j.pax.web.service.http.HttpContext; /** - *

      Resource mapping. Even if "resource handling" is perfomed by servlet container specific {@link javax.servlet.Servlet}, + *

      Resource mapping. Even if "resource handling" is perfomed by servlet container specific {@link jakarta.servlet.Servlet}, * we don't extend {@link ServletMapping} because the servlet is provided by Pax Web itself. The most important field * is single path property, which is:

        *
      • For HttpService: 2nd parameter to - * {@link org.osgi.service.http.HttpService#registerResources(String, String, HttpContext)}
      • + * {@link org.ops4j.pax.web.service.http.HttpService#registerResources(String, String, HttpContext)} *
      • For Whiteboard service: - * {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_RESOURCE_PREFIX} service + * {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_RESOURCE_PREFIX} service * registration property
      • *

      * diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/SecurityConstraintMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/SecurityConstraintMapping.java index 3d14f6c63c..fdf1307b24 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/SecurityConstraintMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/SecurityConstraintMapping.java @@ -15,7 +15,7 @@ */ package org.ops4j.pax.web.service.whiteboard; -import javax.servlet.annotation.ServletSecurity; +import jakarta.servlet.annotation.ServletSecurity; import java.util.Collection; /** diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletContextHelperMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletContextHelperMapping.java index 02fbdf9015..f96a283fe3 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletContextHelperMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletContextHelperMapping.java @@ -16,7 +16,7 @@ package org.ops4j.pax.web.service.whiteboard; import org.osgi.framework.Bundle; -import org.osgi.service.http.context.ServletContextHelper; +import org.osgi.service.servlet.context.ServletContextHelper; /** *

      ServletContextHelper mapping collects all the information required to register a diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletMapping.java index 4aa8bdb2cd..f2ceee5729 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/ServletMapping.java @@ -16,8 +16,8 @@ package org.ops4j.pax.web.service.whiteboard; import java.util.Map; -import javax.servlet.MultipartConfigElement; -import javax.servlet.Servlet; +import jakarta.servlet.MultipartConfigElement; +import jakarta.servlet.Servlet; /** *

      Servlet mapping contains all the information required to register a {@link Servlet} (either directly or @@ -62,7 +62,7 @@ public interface ServletMapping extends ContextRelated { *

      Get a name of the servlet being registered. Matches {@code /} element from * {@code web.xml}.

      *

      In whiteboard method, this can be specified as:

        - *
      • {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_NAME} + *
      • {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_NAME} * property
      • *
      • {@code servlet-name} service registration property (legacy Pax Web Whiteboard approach)
      • *

      @@ -77,9 +77,9 @@ public interface ServletMapping extends ContextRelated { * to Servlet API 4 specification (chapter 12.2) and OSGi CMPN R6+ Whiteboard specification (chapter 140.4). * It matches {@code /} elements from {@code web.xml}.

      *

      In whiteboard method, this can be specified as:

        - *
      • {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_PATTERN} + *
      • {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_PATTERN} * property
      • - *
      • {@link org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletPattern} annotation
      • + *
      • {@link org.osgi.service.servlet.whiteboard.propertytypes.HttpWhiteboardServletPattern} annotation
      • *
      • {@code urlPatterns} service registration property (legacy Pax Web Whiteboard approach)
      • *
      When passing service registration property, it should be one of {@code String}, {@code String[]} or * {@code Collection} types.

      @@ -90,7 +90,7 @@ public interface ServletMapping extends ContextRelated { /** *

      Get an alias to use for servlet registration. An alias is defined in OSGi CMPN specification - * of {@link org.osgi.service.http.HttpService HTTP Service} and is often (even in specification) confused with + * of {@link org.ops4j.pax.web.service.http.HttpService HTTP Service} and is often (even in specification) confused with * servlet name: name in the URI namespace. For the purpose of Pax Web and consistency, single * alias is treated as one-element array of URL Patterns if the patterns are not specified.

      *

      There's no whiteboard specific method to specify an alias.

      @@ -104,9 +104,9 @@ public interface ServletMapping extends ContextRelated { * as error servlet matching {@code /} and {@code /} * elementss from {@code web.xml}.

      *

      In whiteboard method, this can be specified as:

        - *
      • {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_ERROR_PAGE} + *
      • {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_ERROR_PAGE} * property
      • - *
      • {@link org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletErrorPage} annotation
      • + *
      • {@link org.osgi.service.servlet.whiteboard.propertytypes.HttpWhiteboardServletErrorPage} annotation
      • *

      * * @return Servlet async-supported flag @@ -117,9 +117,9 @@ public interface ServletMapping extends ContextRelated { *

      Get flag for supporting asynchronous servlet invocation. It matches {@code /} * element from {@code web.xml}.

      *

      In whiteboard method, this can be specified as:

        - *
      • {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED} + *
      • {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED} * property
      • - *
      • {@link org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletAsyncSupported} + *
      • {@link org.osgi.service.servlet.whiteboard.propertytypes.HttpWhiteboardServletAsyncSupported} * annotation
      • *

      * @@ -132,9 +132,9 @@ public interface ServletMapping extends ContextRelated { * See Servlet API 4 specification (chapter 3.2 File upload) for details. It matches * {@code /} element from {@code web.xml}.

      *

      In whiteboard method, this can be specified as:

        - *
      • {@code org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_MULTIPART_*} + *
      • {@code org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_MULTIPART_*} * properties
      • - *
      • {@link org.osgi.service.http.whiteboard.propertytypes.HttpWhiteboardServletMultipart} annotation
      • + *
      • {@link org.osgi.service.servlet.whiteboard.propertytypes.HttpWhiteboardServletMultipart} annotation
      • *

      * * @return Servlet multipart configuration @@ -145,7 +145,7 @@ public interface ServletMapping extends ContextRelated { *

      Get init parameters for the servlet being registered. It matches {@code /} * elements from {@code web.xml}.

      *

      In whiteboard method, this can be specified as (no annotation here):

        - *
      • {@link org.osgi.service.http.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX} + *
      • {@link org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants#HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX} * prefixed properties (OSGi CMPN Whiteboard approach)
      • *
      • {@code init.} prefixed properties (or prefix may be specified using {@code init-prefix} * service registration property (legacy Pax Web Whiteboard approach)
      • diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/WebSocketMapping.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/WebSocketMapping.java index ff6b878e8b..d890819bb5 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/WebSocketMapping.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/WebSocketMapping.java @@ -21,7 +21,7 @@ * more flexibility and responsibility here.

        * *

        On purpose, we don't allow registration of other objects that usually can be passed (by means of - * {@link javax.servlet.annotation.HandlesTypes} annotation on a {@link javax.servlet.ServletContainerInitializer} + * {@link jakarta.servlet.annotation.HandlesTypes} annotation on a {@link jakarta.servlet.ServletContainerInitializer} * related to WebSockets) by users. Only annontated classes or actual instances are handled and we don't support:

          *
        • {@code javax.websocket.server.ServerApplicationConfig}
        • *
        • {@code javax.websocket.Endpoint}
        • diff --git a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/package-info.java b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/package-info.java index c174527b58..b65684128c 100644 --- a/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/package-info.java +++ b/pax-web-api/src/main/java/org/ops4j/pax/web/service/whiteboard/package-info.java @@ -23,13 +23,13 @@ * only as service properties (Whiteboard specification allows only the latter).

          * *

          Summarizing, whiteboard implementation in Pax Web allows registration of:

            - *
          • actual {@code javax.servlet} elements (servlet, filters, ...), where additional configuration is specified + *
          • actual {@code jakarta.servlet} elements (servlet, filters, ...), where additional configuration is specified * as service registration properties - as described in OSGi CMPN Whiteboard specification.
          • *
          • OSGi services with interfaces ({@link org.osgi.framework.Constants#OBJECTCLASS}) from this package. This * method may be called explicit whiteboard approach and is specific to Pax Web itself.
          • *

          * - *

          Because internally, whiteboard and {@link org.osgi.service.http.HttpService} approaches are + *

          Because internally, whiteboard and {@link org.ops4j.pax.web.service.http.HttpService} approaches are * implemented in very similar fashion, these interfaces are used throughout entire Pax Web.

          * *

          The Mapping suffix of names for interfaces from this package matches the convention taken from diff --git a/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassPathUtilTest.java b/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassPathUtilTest.java index c7b4559878..20d4fcd3dd 100644 --- a/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassPathUtilTest.java +++ b/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassPathUtilTest.java @@ -21,10 +21,9 @@ import java.util.List; import org.apache.commons.io.IOUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class ClassPathUtilTest { @@ -32,25 +31,26 @@ public class ClassPathUtilTest { @Test public void findJUnitClassResources() throws IOException { - assertThat(ClassPathUtil.findEntries(cl, "org", "RunWith.class", false).size(), equalTo(0)); - assertThat(ClassPathUtil.findEntries(cl, "org/junit/runner", "runner/RunWith.class", false).size(), equalTo(0)); - assertThat(ClassPathUtil.findEntries(cl, "org/junit/runner", "runner/RunWith.class", true).size(), equalTo(0)); - - assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org/", "RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "runner/RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "*/RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "runner/RunW*.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "runner/RunWith.*", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "/org", "runner/RunWith.*", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit", "runner/RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit", "runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/", "runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit", "/runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/", "/runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "/org/junit/", "/runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(cl, "/", "RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(cl, null, "RunWith.class", true)); + // org.junit.jupiter.api.Disabled + assertThat(ClassPathUtil.findEntries(cl, "org", "Disabled.class", false).size()).isEqualTo(0); + assertThat(ClassPathUtil.findEntries(cl, "org/junit/jupiter/api", "api/Disabled.class", false).size()).isEqualTo(0); + assertThat(ClassPathUtil.findEntries(cl, "org/junit/jupiter/api", "api/Disabled.class", true).size()).isEqualTo(0); + + assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org/", "Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "api/Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "*/Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "api/Disab*.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org", "api/Disabled.*", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "/org", "api/Disabled.*", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/jupiter", "api/Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/jupiter", "api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/jupiter/", "api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/jupiter", "/api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "org/junit/jupiter/", "/api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "/org/junit/jupiter/", "/api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(cl, "/", "DisplayNameGeneration.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(cl, null, "DisplayNameGeneration.class", true)); } @Test @@ -80,7 +80,7 @@ public void findResourcesInJARs() throws IOException { urls = ClassPathUtil.jarToItsClassPath(urls[0]); } for (URL url : urls) { - if (url.toExternalForm().contains("junit/junit")) { + if (url.toExternalForm().contains("org/junit/jupiter/junit-jupiter-api")) { if ("jar".equals(url.getProtocol())) { roots[0] = url; } else { @@ -90,35 +90,35 @@ public void findResourcesInJARs() throws IOException { } } - assertThat(ClassPathUtil.findEntries(null, roots, "org", "RunWith.class", false).size(), equalTo(0)); - assertThat(ClassPathUtil.findEntries(null, roots, "org/junit/runner", "runner/RunWith.class", false).size(), equalTo(0)); - assertThat(ClassPathUtil.findEntries(null, roots, "org/junit/runner", "runner/RunWith.class", true).size(), equalTo(0)); - - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/", "RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "runner/RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "*/RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "runner/RunW*.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "runner/RunWith.*", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "/org", "runner/RunWith.*", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit", "runner/RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit", "runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/", "runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit", "/runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/", "/runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "/org/junit/", "/runner/RunWith.class", false)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, "/", "RunWith.class", true)); - assertCorrectClass(ClassPathUtil.findEntries(null, roots, null, "RunWith.class", true)); + assertThat(ClassPathUtil.findEntries(null, roots, "org", "Disabled.class", false).size()).isEqualTo(0); + assertThat(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter/api", "api/Disabled.class", false).size()).isEqualTo(0); + assertThat(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter/api", "api/Disabled.class", true).size()).isEqualTo(0); + + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/", "Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "api/Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "*/Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "api/Disab*.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org", "api/Disabled.*", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "/org", "api/Disabled.*", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter", "api/Disabled.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter", "api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter/", "api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter", "/api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "org/junit/jupiter/", "/api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "/org/junit/jupiter/", "/api/Disabled.class", false)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, "/", "DisplayNameGeneration.class", true)); + assertCorrectClass(ClassPathUtil.findEntries(null, roots, null, "DisplayNameGeneration.class", true)); } - private void assertCorrectClass(List urls) { - assertThat(urls.size(), equalTo(1)); + private static void assertCorrectClass(List urls) { + assertThat(urls.size()).isEqualTo(1); try (InputStream is = urls.get(0).openConnection().getInputStream()) { byte[] clazz = IOUtils.toByteArray(is); - assertThat(clazz[0], equalTo((byte) 0xCA)); - assertThat(clazz[1], equalTo((byte) 0xFE)); - assertThat(clazz[2], equalTo((byte) 0xBA)); - assertThat(clazz[3], equalTo((byte) 0xBE)); + assertThat(clazz[0]).isEqualTo((byte) 0xCA); + assertThat(clazz[1]).isEqualTo((byte) 0xFE); + assertThat(clazz[2]).isEqualTo((byte) 0xBA); + assertThat(clazz[3]).isEqualTo((byte) 0xBE); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } diff --git a/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassSpaceTest.java b/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassSpaceTest.java index 15351e705a..75bdd46ce3 100644 --- a/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassSpaceTest.java +++ b/pax-web-api/src/test/java/org/ops4j/pax/web/utils/ClassSpaceTest.java @@ -22,7 +22,7 @@ import java.net.URLClassLoader; import java.util.Enumeration; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/pax-web-api/src/test/java/org/ops4j/pax/web/utils/UrlTest.java b/pax-web-api/src/test/java/org/ops4j/pax/web/utils/UrlTest.java index 2bcc507bf9..2a673c480b 100644 --- a/pax-web-api/src/test/java/org/ops4j/pax/web/utils/UrlTest.java +++ b/pax-web-api/src/test/java/org/ops4j/pax/web/utils/UrlTest.java @@ -17,7 +17,7 @@ import java.net.URL; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.core.io.UrlResource; public class UrlTest {