Uploaded image for project: 'MyFaces Core'
  1. MyFaces Core
  2. MYFACES-334

aliasbean and alias usage in binding

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.0.9m9
    • None
    • None
    • None

    Description

      Myfaces fails to restore a view it it uses aliases in bindings.

      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);
      }
      }

      Attachments

        Activity

          People

            mmarinschek Martin Marinschek
            imario Mario Ivankovits
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: