Hi,

 In our application, we would like to have a modular structure, where for a
certain DTO, we would like to have different tabs, depending on the actual
deployed application, so the core webapp doesn't need to know all the
possible tabs in advance.
We have the following interface:

interface TabProvider {
  String getTabTitle(Object obj);
  Block getTabComponent(Object obj);
 // etc ...
}

And we have a service, which collects all the TabProviders, filters, and
displays all the provided blocks.
Just we have to construct the 'Block'-s from the plugins. I've checked
Tapestry, and found out (for example in PropertyDisplayBlock),
this should work:

class MyPlugin implements TabProvider {
  ComponentClassResolver resolver;
  RequestPageCache pageCache;

 public Block getTabComponent(Object obj) {
    String pageName =
resolver.resolvePageClassNameToPageName(MyPluginTab.class.getName());
    Page page = pageCache.get(pageName);
    return page.getRootElement().getBlock("content");
  }
}

So far, so good. It works :) Of course, it could be just an fortunate
accident.

The problem occurs, when I try to pass a parameter to that block / page, as
I can't modify the page or the block anyway.
I've tried two things:
 1, MyPluginTab tab = (MyPluginTab) page.getRootComponent();
     tab.init(...);
      This creates a nice exception: *java.lang.ClassCastException:
x.y.z.MyPluginTab cannot be cast to x.y.z.MyPluginTab *
      Clearly a class loader issue
  2, Using the 'environment' infrastructure, so in the block embedding
component:

@BeforeRender
void beforeRender() {
  environment.push(ObjSupplier.class, new ObjSupplier() { Object get() {
return obj; } });
}

@AfterRender
void after() {
  environment.pop(ObjSupplier.class);
}

And in the MyPluginTab:
    @Environmental
    private ObjSupplier objSupplier;

This seem to be work ... For the first request. On the subsequent AJAX
requests, the parent component rendering is not called, so the ObjSupplier
is not pushed to stack, and the page wont work any more.

What should I do, to ensure that the wrapper class beforeRender/afterRender
method is called? Or where else should I put the pusp/pop logic ? Or what
do you think, how can I solve this problem?

Thanks in advance

 Zsombor

Reply via email to