Hi all,
I don't know if I am writing in appropriate place, but assume that I am ;)
So ... for some time, me and my friend are trying to create JSF
application in OSGi environment.
This application should be composed form core element and it's plug-ins.
Each plug-in (OSGi bundle) can be install installed or uninstalled in
run-time. Application should be aware of its plug-ins and its lifecycle
(installing/uninstalling) without being restarted.
To do so, we are combining few technologies: JSF (MyFaces) + PrimeFaces
+ Hibernate + Spring + OSGi (Equinox) + SpringDM (will be exchange to
blueprint).
To simplicy prototype we are going to use JSF + Spring + Spring-DM +
OSGi only.
As we have realized, JSF has not been planned to work with dynamic
components (plug-ins) that can provide new views (xhtml pages),
resources or manageable-beans. But specification of JSF allows to swap
some application's modules/components.
I have figure out some mechanism for providing views and resources
(manageable beans is quite more complicated and it is not part of my
question now :)) in run-time without violate JSF specification (in my
opinion ofcourse :)).
So our application is working in OSGi environment. The core is typical
JSF application deployed to Tomcat (thanks to Spring-DM) which is also
running in OSGi environment. Each plug-in is simply OSGi bundle that has
dependency to Core. In Core there is PluginsResolverService that is
responsible for detecting Core's available plug-in (assume that we are
keeping Bundle descriptor).
To provide views and resources in run-time (it is actuali working !) I
have done 2 things:
1) I have implemented my own ExternalContext and ExternalContextFactory.
Now we want to be aware of OSGi context not only about Servlet context,
I have implemented:
OsgiAwareExternalContextFactory which is quite simmilar to default
implementation. There are 2 differences. This class in constructor
requires ExternalContextFactory (decorator design pattern <- it is part
of JSF specification). The second difference is that we thos factory
provides OsgiAwareExternalContext that in constructor requires
ExternalContext (which we can obtain from original ExternalContextFactory).
OsgiAwareExternalContext (so far) delegates all of its method to
original ExternalContext except of getResource(String) method. This
method is using PluginsResolverService to obtain all plug-ins and to
look if they are not containing resource that we are looking for.
2) I have implemented my own Servlet for handling non-faces request of
resources.
That is all. Now if i'am installing plug-in that provides view:
someView.xhtml, I'am able to display it (I'am typing in web browser:
{Context path of Core}/someView.xhtml). But there is one problem. JSF
caches views. So if plug-in will be uninstalled, page someView.xhtml is
still visible for users.
I have found that DefaultFaceletFactory is responsible for caching
views. And here is my question.
If I want to provide my own FaceletFactory implementation I have to
provide brand new implementarion of ViewDeclarationLanguageFactory !!!
Standard implementation of ViewDeclarationLanguageFactory which is
ViewDeclarationLanguageFactoryImpl creates in initialize() method
FaceletViewDeclarationLanguageStrategy that is creating in constructor
FaceletViewDeclarationLanguage that is creating in initialize() method
FaceletFactory (DefaultFaceletFactory).
FaceletViewDeclarationLanguage has protected method
createFaceletFactory(FacesContext, Compiler) (wchich is called in
initialize() method) that is responsible for creating FaceletFactory.
But even it is protected method that I Can override I cannot provide my
own implementation of ViewDeclarationLanguageBase (which will extends
FaceletViewDeclarationLanguage) because there is no way of informing
FaceletViewDeclarationLanguageStrategy thats should use my
implementation. Shouldn't it be possible ?
Sorry for my English :)
--
Pozdrawiam,
Kamil Soboń
iso.poczta(at)gmail.com
sobon(at)student.agh.edu.pl