Interface ContextRelated

  • All Known Subinterfaces:
    ErrorPageMapping, FilterMapping, JspMapping, ListenerMapping, ResourceMapping, ServletMapping, WebSocketMapping, WelcomeFileMapping

    public interface ContextRelated

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

    Context is something different in HttpService case (it's represented by HttpContext) and in Whiteboard case (it's represented by ServletContextHelper). In both cases, eventually this context is actually backed by a real ServletContext from Java Servlet API. Though it's not 1:1 relation...

    Both HttpContext and ServletContextHelper do not specify a context path. It can be specified only by:

    • (Pax Web legacy Whiteboard) httpContext.path service registration property when whiteboard-registering HttpContext service
    • (Pax Web legacy Whiteboard) whiteboard-registering a HttpContextMapping service with a path
    • (OSGI CMPN Whiteboard) HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH service registration property when registering ServletContextHelper service

    The referenced context doesn't have to be unique wrt 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) ServletContextHelper (new Whiteboard) instance for given context path, but actual (server specific) context (or web application) may be supported by different ServletContextHelper instances.

    Pax Web will unify behavior of Http Service and Whiteboard style contexts (knowing that underneath there's actual, server-specific ServletContext) and uniqueness will be checked by String ID (and bundle for bundle-scoped access). Additionally for old-style 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 HttpService case (no whiteboard), equality of HttpContext created by users is implied to be instance equality (same object). Pax Web wraps such contexts and sets custom context ID in the wrapper.

    In non-whiteboard approach, servlets are always registered together with associated HttpContext when calling method like HttpService.registerServlet(java.lang.String, javax.servlet.Servlet, java.util.Dictionary<?, ?>, org.osgi.service.http.HttpContext). User may also provide WebContainerContext or 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 HttpContext when using old HttpService methods, user first needs to register HttpContextMapping OSGi service or HttpContext service with httpContext.id registration property:

         // register pure HttpContext service
         props.put("httpContext.id", "my-context");
         bundleContext.registerService(HttpContext.class, aContext, props);
    
         // or register HttpContextMapping using "explicit whiteboard approach"
         aContextMapping = new HttpContextMappingImpl();
         aContextMapping.setContextId("my-context");
         aContextMapping.setHttpContext(new HttpContext() { ... });
         bundleContext.registerService(HttpContextMapping.class, aContextMapping, null);
     

    Then, an element (like servlet) may be registered like this:

         context = new DefaultHttpContext(bundleContext.getBundle(), "my-context");
         httpService.registerServlet("/alias", servlet, null, context);
     

    This trick is based on assumed identity of DefaultHttpContext, which is name+bundle and separates the identity from context behavior (HttpContext.handleSecurity(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)), which should not be specified (or emphasized) in every registration.

    • Method Detail

      • getContextSelectFilter

        String getContextSelectFilter()

        Get an LDAP-style filter to select 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 (ServletContextHelper in case of Whiteboard) is registered using:

             Dictionary props = new Hashtable<>();
             props.put("osgi.http.whiteboard.context.name", "my-context");
             props.put("osgi.http.whiteboard.context.path", "/my-context");
             context.registerService(ServletContextHelper.class, ..., props);
         
        Servlet may be associated with such context using:
             Dictionary props = new Hashtable<>();
             props.put("osgi.http.whiteboard.context.select", "(osgi.http.whiteboard.context.name=my-context)");
             context.registerService(Servlet.class, ..., props);
         

        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 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);
         

        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 ServletContextHelper with the registration property osgi.http.whiteboard.context.httpservice.

        This seems a bit artificial:

        • We can't distinguish actual old-style context (HttpContext)
        • Specification requires the implementation to register special ServletContextHelper representing a HttpContext

        Returns:
      • getContextId

        String getContextId()

        Get an ID of the context in which the servlet should be registered. This is handy simplification of context association if no getContextSelectFilter() is specified.

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

        • standard (Whiteboard) osgi.http.whiteboard.context.select=(osgi.http.whiteboard.context.name=name) service registration property
        • legacy (Pax Web specific) httpContext.id=name service registration property
        • this method (if user registers an instance of ContextRelated.

        Returns:
        id of single context this whiteboard element should be associated with