dev@javaserverfaces.java.net

Questions regarding InjectionApplicationFactory

From: <egore_at_gmx.de>
Date: Mon, 17 Oct 2011 08:37:10 +0000 (GMT)

Hi list,

I'm currently facing an issue with the InjectionApplicationFactory.
When
creating the application it performs an injectDefaultApplication().
This sets
a private field "defaultApplication" in the created application. But:
Applications can have a delegate. And delegates can have delegates
themselves.

I have the following hierarchie of applications:

ApplicationType1
- defaultApplication: ApplicationImpl
- delegate: ApplicationType2
  - defaultApplication: null
  - delegate: ApplicationImpl.
    - defaultApplication: null

Now I have ApplicationType1 that has the defaultApplication and all
members in
the hierarchie don't. ApplicationType1 implements getResourceHandler()
the
following way:

public ResourceHandler getResourceHandler() {
  return getDelegate().getResourceHandler();
}

Now this get's passed to ApplicationType2 (which is an implementation
from
JSF 1.2) which call Mojarras Application's getResourceHandler(),
implemented like this:

public ResourceHandler getResourceHandler() {
  if (defaultApplication != null) {
    return defaultApplication.getResourceHandler();
  }
  throw new UnsupportedOperationException();
}

Now you can obviously see that this is never going to work, as
defaultApplication will always be null.

I tried to work around this issue by using the attached patch. This
patch
assumes that ever Application has to store it's delegate in a private
member
variable. The loop I added was meant to find this field (and therefore
the
delegate) and also set the default application in this delegate. Sadly
this
does not work (because app.getClass().getDeclaredFields() never returns
any
fields) and also is not really reliable and a hack.

Anyone has a better solution to this problem?

Thanks in advance,
 Christoph

--- com/sun/faces/application/InjectionApplicationFactory.java
+++ com/sun/faces/application/InjectionApplicationFactory.java
@@ -142,7 +142,22 @@ public class InjectionApplicationFactory extends
ApplicationFactory implements F
                                
.getDeclaredField("defaultApplication");
                     defaultApplicationField.setAccessible(true);
                 }
- defaultApplicationField.set(application,
defaultApplication);
+ Application app = application;
+ do {
+ defaultApplicationField.set(application,
defaultApplication);
+ boolean found = false;
+ for (Field field :
app.getClass().getDeclaredFields()) {
+ if (field.getType() == Application.class) {
+ field.setAccessible(true);
+ app = (Application) field.get(app);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ app = null;
+ }
+ } while (app != null);
 
             } catch (NoSuchFieldException nsfe) {
                 if (LOGGER.isLoggable(Level.FINE)) {