public final class OsgiContextModel extends Identity implements Comparable<OsgiContextModel>
This class represents OSGi-specific HttpContext/ServletContextHelper
and points to single, server-specific ServletContext and (at model level) to single
ServletContextModel. It maps directly 1:1 to an OSGi service registered by user:
HttpContext with legacy Pax Web servier registration propertiesServletContextHelper with standard properties and/or annotationsHttpContextMappingServletContextHelperMappingOsgiContextModel, while related 1:1 with single
ephemeral context, it can be associated with multiple ServletContextHelper or
HttpContext instances, because the original ServiceReference can represent
ServiceFactory, so many bundles may obtain different instances of target
context.
Discovered service registration properties are stored as well to ensure proper context selection according to 140.3 Common Whiteboard Properties.
The most important role is to wrap actual HttpContext or
ServletContextHelper that'll be used when given servlet will be accessing
own ServletContext, to comply with Whiteboard Specification.
While many OSGi-related contexts may point to single ServletContextModel and
contribute different web elements (like some bundles provide servlets and other bundle provides login configuration),
some aspects need conflict resolution - for example session timeout setting. Simply highest ranked
OsgiContextModel will be the one providing the configuration for given ServletContextModel.
Some aspects of ServletContext visible to registered element are however dependent on which particular
OsgiContextModel was used. Resource access will be done through HttpContext or
ServletContextHelper and context parameters will be stored in this
class (remember: there can be different OsgiContextModels for the same ServletContextModel, but
providing different init parameters (<context-param> from web.xml).
Another zen-like question: there may be two different ServletContextHelper
services registered for the same context path with different
ServletContextHelper.handleSecurity(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse). Then two filters are registered
to both of such contexts - looks like when sending an HTTP request matching this common context path,
both handleSecurity() methods must be called before entering the filter pipeline. Fortunately
specification is clear about it. "140.5 Registering Servlet Filters" says:
Servlet filters are only applied to servlet requests if they are bound to the same Servlet Context Helper and the same Http Whiteboard implementation.
In Felix-HTTP, N:1 mapping between many OsgiContextModel and ServletContextModel relationship
is handled by org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry. And
org.apache.felix.http.base.internal.registry.HandlerRegistry#registrations is sorted using 3 criteria:
Shadowing OsgiContextModel (see
DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE) can happen
only when there's name/id conflict, so:
default context, for example by changing its context pathOsgiContextModel pointing to the same context path, only
one should be used (registered into actual server-specific ServletContext - again, according to service
rankingServletConfig.getServletContext())
with own OsgiContextModel, but there are things to do before actual request processing - like
calling ServletContainerInitializer.onStartup(Set, ServletContext) methods. Here, the
OsgiContextModel passed to such calls is the highest ranked OsgiContextModel /
OsgiServletContext which may be different that the context
associated with the servlets running in such context.registerXXX methods on WebContainer, by default (or
explicitly) some bundle-scoped instance of HttpContext is used (mapped internally again to some
OsgiContextModel, but when Whiteboard is enabled, the OsgiContextModel that is highest-ranked
for given ServletContext (and particular context path) is usually the "default" OsgiContextModel
created for Whiteboard (shared by default and associated with pax-web-extender-whiteboard bundle, which may
not be the best source of e.g., resources loaded through ServletContextHelper.getResource(String)
until a bundle-scoped instance of ServletContextHelper is created for a bundle that registers some
web elements.OsgiContextModel may represent legacy (Http Service specification) context and standard
(Whiteboard Service specification) context. If it's created (customized) for HttpContext
(registered directly or via HttpContextMapping) and if it's a
singleton, then such OsgiContextModel is equivalent to one created directly through
HttpService and user may continue to register servlets via
HttpService to such contexts. That's the way to change the context path of such
context. Without any additional steps, the servlets (and filters and resources) registered through
WebContainer will always be associated with OsgiContextModel
that is lower ranked than the "default" OsgiContextModel coming from Whiteboard.
| Modifier and Type | Field and Description |
|---|---|
static OsgiContextModel |
DEFAULT_CONTEXT_MODEL
The singleton
OsgiContextModel used both by pax-web-runtime and pax-web-extender-whiteboard |
static org.slf4j.Logger |
LOG |
| Constructor and Description |
|---|
OsgiContextModel(org.osgi.framework.Bundle ownerBundle,
Integer rank,
Long serviceId,
boolean whiteboard) |
OsgiContextModel(org.ops4j.pax.web.service.WebContainerContext httpContext,
org.osgi.framework.Bundle ownerBundle,
String contextPath,
boolean whiteboard) |
| Modifier and Type | Method and Description |
|---|---|
void |
addJspPropertyGroupDescriptor(javax.servlet.descriptor.JspPropertyGroupDescriptor descriptor) |
void |
addTagLibs(Collection<javax.servlet.descriptor.TaglibDescriptor> tagLibs) |
void |
addUnregistrationChange(Change unregistration)
At
OsgiContextModel level we track a list of changes that represent implicit
unregistrations of dynamic servlets/filters/listeners that may have been added for example inside
ServletContainerInitializer.onStartup(Set, ServletContext) method. |
int |
compareTo(OsgiContextModel o) |
OsgiServletContextClassLoader |
getClassLoader() |
List<String> |
getConnectors() |
Map<String,String> |
getContextParams() |
String |
getContextPath() |
org.osgi.framework.ServiceReference<?> |
getContextReference() |
Hashtable<String,Object> |
getContextRegistrationProperties() |
BiFunction<org.osgi.framework.BundleContext,String,org.ops4j.pax.web.service.WebContainerContext> |
getContextSupplier() |
org.ops4j.pax.web.service.WebContainerContext |
getDirectHttpContextInstance()
If caller knows there's a direct reference to
WebContainerContext (wrapping an instance
of HttpContext or ServletContextHelper), then we can get this context without "resulution"
process. |
String |
getDisplayName() |
int |
getDtoFailureCode() |
protected String |
getIdPrefix() |
Map<String,Object> |
getInitialContextAttributes() |
javax.servlet.descriptor.JspConfigDescriptor |
getJspConfigDescriptor()
Method to support
ServletContext.getJspConfigDescriptor() |
String |
getName() |
org.osgi.framework.Bundle |
getOwnerBundle() |
SecurityConfigurationModel |
getSecurityConfiguration() |
List<URL> |
getServerSpecificDescriptors() |
long |
getServiceId() |
int |
getServiceRank() |
SessionConfigurationModel |
getSessionConfiguration() |
String |
getTemporaryLocation()
Each
OsgiContextModel should have separate "working directory" and this method returns such relative
path depending on contextPath and getName() |
List<Change> |
getUnregistrations() |
List<String> |
getVirtualHosts() |
boolean |
hasDirectHttpContextInstance()
Checks if this
OsgiContextModel has direct instance (not bound to any Bundle) of
WebContainerContext. |
boolean |
isAsynchronusRegistration() |
boolean |
isShared()
Returns
true if the model represents Whiteboard context (ServletContextHelper) or
it represents old HttpContext provided as direct (not a service reference) and is an
instance of MultiBundleWebContainerContext. |
boolean |
isValid()
This method should be called from Whiteboard infrastructure to really perform the validation and set
isValid flag, which is then used for "Failure DTO" purposes.
|
boolean |
isWab()
A "WAB" context is always created by pax-web-extender-war when a WAB is installed and provides dedicated,
direct (no service reference and no supplier) to
HttpContext. |
boolean |
isWhiteboard()
A "whiteboard" context can override implicit "httpservice" context.
|
Boolean |
performValidation()
Perform context-specific validation and throws different exceptions when needed.
|
void |
releaseHttpContext(org.osgi.framework.Bundle bundle)
Call
BundleContext.ungetService(ServiceReference) for given bundle if needed, to release the
WebContainerContext reference. |
org.ops4j.pax.web.service.WebContainerContext |
resolveHttpContext(org.osgi.framework.Bundle bundle)
This method gets a
WebContainerContext asociated with given model. |
void |
setAsynchronusRegistration(boolean async) |
void |
setClassLoader(OsgiServletContextClassLoader classLoader)
In Whiteboard and HttpService scenarios,
OsgiServletContextClassLoader is created in the wrapper
for actual server runtime (to include the bundle specific to given runtime). |
void |
setContextPath(String contextPath) |
void |
setContextReference(org.osgi.framework.ServiceReference<?> contextReference) |
void |
setContextSupplier(BiFunction<org.osgi.framework.BundleContext,String,org.ops4j.pax.web.service.WebContainerContext> contextSupplier) |
void |
setDisplayName(String displayName) |
void |
setHttpContext(org.ops4j.pax.web.service.WebContainerContext httpContext) |
void |
setName(String name) |
void |
setOwnerBundle(org.osgi.framework.Bundle ownerBundle) |
void |
setServiceId(long serviceId) |
void |
setServiceRank(int serviceRank) |
void |
setSessionCookieConfig(javax.servlet.SessionCookieConfig config) |
void |
setSessionTimeout(Integer minutes) |
void |
setShared(Boolean shared) |
void |
setWab(boolean wab) |
org.osgi.service.http.runtime.dto.ServletContextDTO |
toDTO()
Called on demand when someone wants to create
successful DTO from this
OsgiContextModel |
org.osgi.service.http.runtime.dto.FailedServletContextDTO |
toFailedDTO(int failureReason)
Called on demand when someone wants to create
failed DTO from this
OsgiContextModel, specifying a reason of failure. |
String |
toString() |
equals, getId, getNumericId, hashCodepublic static final org.slf4j.Logger LOG
public static final OsgiContextModel DEFAULT_CONTEXT_MODEL
OsgiContextModel used both by pax-web-runtime and pax-web-extender-whiteboardpublic OsgiContextModel(org.osgi.framework.Bundle ownerBundle,
Integer rank,
Long serviceId,
boolean whiteboard)
public OsgiContextModel(org.ops4j.pax.web.service.WebContainerContext httpContext,
org.osgi.framework.Bundle ownerBundle,
String contextPath,
boolean whiteboard)
protected String getIdPrefix()
getIdPrefix in class Identitypublic boolean isValid()
This method should be called from Whiteboard infrastructure to really perform the validation and set isValid flag, which is then used for "Failure DTO" purposes.
public Boolean performValidation() throws Exception
Perform context-specific validation and throws different exceptions when needed.
This method should be called in Http Service scenario where we immediately need strong feedback - with exceptions thrown for all validation problems.
Exceptionpublic org.ops4j.pax.web.service.WebContainerContext resolveHttpContext(org.osgi.framework.Bundle bundle)
This method gets a WebContainerContext asociated with given model. If the context is not
configured directly, we may need to dereference it if needed.
It's both obvious and conformant to Whiteboard Service specification, that ServletContextHelper
may be registered as ServiceFactory (and default one behaves
exactly like this), so it must be dereferenced within a context of given Whiteboard service's (e.g., Servlet's)
BundleContext).
Similar case is in Pax Web, when user registers HttpContextMapping
or ServletContextHelperMapping. Relevant method may create new
instance of the context on each call (but the getHttpContext()/getServletContextHelper() doesn't
accept BundleContext).
bundle - public void releaseHttpContext(org.osgi.framework.Bundle bundle)
BundleContext.ungetService(ServiceReference) for given bundle if needed, to release the
WebContainerContext reference.bundle - public void addUnregistrationChange(Change unregistration)
At OsgiContextModel level we track a list of changes that represent implicit
unregistrations of dynamic servlets/filters/listeners that may have been added for example inside
ServletContainerInitializer.onStartup(Set, ServletContext) method.
JavaEE doesn't bother with unregistration of such elements, but Pax Web does ;)
unregistration - public String getName()
public void setName(String name)
public String getDisplayName()
public void setDisplayName(String displayName)
public org.osgi.framework.Bundle getOwnerBundle()
public void setOwnerBundle(org.osgi.framework.Bundle ownerBundle)
public String getContextPath()
public void setContextPath(String contextPath)
public int getServiceRank()
public void setServiceRank(int serviceRank)
public long getServiceId()
public void setServiceId(long serviceId)
public org.osgi.framework.ServiceReference<?> getContextReference()
public void setContextReference(org.osgi.framework.ServiceReference<?> contextReference)
public BiFunction<org.osgi.framework.BundleContext,String,org.ops4j.pax.web.service.WebContainerContext> getContextSupplier()
public void setContextSupplier(BiFunction<org.osgi.framework.BundleContext,String,org.ops4j.pax.web.service.WebContainerContext> contextSupplier)
public void setHttpContext(org.ops4j.pax.web.service.WebContainerContext httpContext)
public OsgiServletContextClassLoader getClassLoader()
public void setClassLoader(OsgiServletContextClassLoader classLoader)
OsgiServletContextClassLoader is created in the wrapper
for actual server runtime (to include the bundle specific to given runtime). But in WAB case, we already
have some set of bundles collected as reachable bundles.classLoader - public boolean hasDirectHttpContextInstance()
OsgiContextModel has direct instance (not bound to any Bundle) of
WebContainerContext. Such OsgiContextModel represents the context from the point
of view of Http Service specification (in Whiteboard, context should be obtained from service registry
when needed, because it's recommended to register it as ServiceFactory).public org.ops4j.pax.web.service.WebContainerContext getDirectHttpContextInstance()
WebContainerContext (wrapping an instance
of HttpContext or ServletContextHelper), then we can get this context without "resulution"
process.public boolean isShared()
true if the model represents Whiteboard context (ServletContextHelper) or
it represents old HttpContext provided as direct (not a service reference) and is an
instance of MultiBundleWebContainerContext.public void setShared(Boolean shared)
public int getDtoFailureCode()
public void addTagLibs(Collection<javax.servlet.descriptor.TaglibDescriptor> tagLibs)
public void addJspPropertyGroupDescriptor(javax.servlet.descriptor.JspPropertyGroupDescriptor descriptor)
public javax.servlet.descriptor.JspConfigDescriptor getJspConfigDescriptor()
ServletContext.getJspConfigDescriptor()public void setSessionTimeout(Integer minutes)
public void setSessionCookieConfig(javax.servlet.SessionCookieConfig config)
public SessionConfigurationModel getSessionConfiguration()
public SecurityConfigurationModel getSecurityConfiguration()
public boolean isWhiteboard()
HttpService scenario.public boolean isWab()
HttpContext.public void setWab(boolean wab)
public void setAsynchronusRegistration(boolean async)
public boolean isAsynchronusRegistration()
public int compareTo(OsgiContextModel o)
compareTo in interface Comparable<OsgiContextModel>public String getTemporaryLocation()
OsgiContextModel should have separate "working directory" and this method returns such relative
path depending on contextPath and getName()public org.osgi.service.http.runtime.dto.ServletContextDTO toDTO()
successful DTO from this
OsgiContextModelpublic org.osgi.service.http.runtime.dto.FailedServletContextDTO toFailedDTO(int failureReason)
failed DTO from this
OsgiContextModel, specifying a reason of failure.failureReason - Copyright © 2006–2024 OPS4J - Open Participation Software for Java. All rights reserved.