tags:

views:

331

answers:

1

Hi,

I've written a facelet, and a corresponding backing bean, that implements user management (addition, deletion and so on).

I'd want to be able to perform some custom processing when, for instance, a new user is added.

There is a "create" button in the facelet, whose click event is handled by its backing bean. At the end of the event handler, I'd want to be able to call a method of another backing bean, which is not known because ideally the facelet can be used in several pages, with different custom processing.

I thought to implement this feature by providing to the facelet a backing bean name and a method name, like this:

<myfacelet:subaccounts 
    backingBean="myBackingBean" 
    createListener="createListener" />

and at the end of the event handler call #{myBackingBean.createListener} someway.

I'm using this method (along with some overloads) to obtain a MethodExpression:

protected MethodExpression getMethodExpression(String beanName, String methodName, Class<?> expectedReturnType, Class<?>[] expectedParamTypes)
{
    ExpressionFactory expressionFactory;
    MethodExpression method;
    ELContext elContext;
    String el;

    el = String.format("#{%s['%s']}", beanName, methodName);
    expressionFactory = getApplication().getExpressionFactory();
    elContext = getFacesContext().getELContext();
    method = expressionFactory.createMethodExpression(elContext, el, expectedReturnType, expectedParamTypes);

    return method;
}

and the click event handler should look like:

public void saveSubaccountListener(ActionEvent event)
{
    MethodExpression method;

    ...

    method = getMethodExpression(
            "backingBean", 
            "createSubaccountListener", 
            SubuserBean.class);
    if (method != null)
        method.invoke(
            getFacesContext().getELContext(), 
            new Object[] { _editedSubuser });
}

That works fine as long as I provide an existing bean name (myBackingBean), but if I use backingBean the invoke() doesn't work due to the following error:

javax.el.PropertyNotFoundException: Target Unreachable, 
identifier 'backingBean' resolved to null

Is there a way I can retrieve from the facelet backing bean the value of a parameter that has been passed to the facelet? In my case, the value of backingBean, which should be myBackingBean?

I've searched for and tried different solutions, but with no luck yet.

A: 

This is general template. We'll later pass parameter to this template:

<ui:composition>
    <!-- param: reportsBean, type: ReportsController, required -->
    <h:outputText value="#{reportsBean.report}"/>
</ui:composition>

And here we pass the parameters:

<ui:include src="/WEB-INF/template/reports/lineChart.xhtml">
     <ui:param name="reportsBean" value="#{categoryReports}"/>
</ui:include>
Roman
This doesn't seem to solve my problem. I already have access to the backing bean from the facelet jsf code, but not from the facelet backing bean.Btw I tried your code, the output text works fine, but when I try to use MethodExpression.invoke() it doesn't - same error
Antonio