You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Mario Ivankovits <ma...@ops.co.at> on 2005/07/14 08:07:15 UTC

aliasbean and alias usage in binding

Hi!

I hope its not wrong to post this to the developer list at first, but I 
think there is a technical problem with the aliasbean.

Our jsf looks like this (for sure, we use include for the dataTable):

<x:aliasBeansScope>
    <x:aliasBean alias="#{coTopicEdit}" value="#{coAddressEdit}" />
    <h:dataTable var="topic" value="#{coTopicEdit.topics}"
                binding="#{coTopicEdit.genericTopicTable}" >
....
    </h:dataTable>
    <h:commandLink value="xx"/>
</x:aliasBeansScope>


The page renders correctly for the first time, but if you press the 
commandLink myfaces fails in the restoreView phase.
The reason is simple:
During LifecycleImpl.restoreView myfaces tries to attach each component 
to the backing bean (in recursivelyHandleComponentReferencesAndSetValid 
- "binding.setValue").
Now if it comes to the binding of the dataTable the alias bean havent 
had the chance to reassign its alias and thus the ValueBinding for 
"#{coTopicEdit.genericTopicTable}" fails.


To workaround it I create my own ViewHandler (code follows).
I hooked into restoreView - process the view recursivley and call 
"makeAlias" on each alias bean using reflection (the method is package 
private).
This IS a hack and (I think) it breaks the scope of the alias , but for 
now I am happy with it.

Any ideas how to solve it correctly?

And now the code in case someone else needs it too:

    public UIViewRoot restoreView(FacesContext facesContext, String viewId)
    {
        UIViewRoot root = super.restoreView(facesContext, viewId);
        if (root != null)
        {
            processAliases(facesContext, root);
        }
        return root;
    }

    protected void processAliases(FacesContext context, UIComponent root)
    {
        if (root == null)
        {
            return;
        }

        for (Iterator it = root.getFacetsAndChildren(); it.hasNext(); )
        {
            UIComponent component = (UIComponent)it.next();

            if (component instanceof AliasBean)
            {
                AliasBean alias = (AliasBean) component;
                try
                {
                    Method makeAliasMethod = 
alias.getClass().getDeclaredMethod("makeAlias", FacesContext.class);
                    makeAliasMethod.setAccessible(true);
                    makeAliasMethod.invoke(alias, context);
                }
                catch (NoSuchMethodException e)
                {
                    log.warn(e.getLocalizedMessage(), e);
                }
                catch (IllegalAccessException e)
                {
                    log.warn(e.getLocalizedMessage(), e);
                }
                catch (InvocationTargetException e)
                {
                    log.warn(e.getLocalizedMessage(), e);
                }
            }

            processAliases(context, component);
        }
    }


---
Mario