[jbossseam-issues] [JBoss JIRA] Created: (JBSEAM-3935) <render> elements in pages.xml need to fallthrough like in case statements.

Dan Hinojosa (JIRA) jira-events at lists.jboss.org
Wed Feb 4 16:55:44 EST 2009


<render> elements in pages.xml need to fallthrough like in case statements.
---------------------------------------------------------------------------

                 Key: JBSEAM-3935
                 URL: https://jira.jboss.org/jira/browse/JBSEAM-3935
             Project: Seam
          Issue Type: Feature Request
            Reporter: Dan Hinojosa


I found a situation where having a Renderer object injected into a bean is not at all ideal.  Case in point, resetting a password.  In example 1, when I call renderer.render, the user object has not be outjected yet.  Therefore if I have information in /email/password.xhtml referring to #{user.password} the email will send either nothing or the old password.  In example 2, I can get around it with a kludge which is updating the user object injected and then do the render.  This is inelegant.  The best option I believe is to do the rendering outside of the method, so I propose doing something like in example 3.

Example 1:

@Name("registrationBean")
@Scope(ScopeType.CONVERSATION)
public class RegistrationBean implements Serializable {
    @In
    private EntityManager entityManager;

    @In @Out
    private User user;

    @In
    private Renderer renderer;

    @In //Ostermiller random password utility
    private RandPass randPass;

    @Transactional
    public void resetPassword() {
        Query query = entityManager.createQuery("SELECT u from User u where UPPER(u.email) = UPPER(:email)");
        query.setParameter("email", user.getEmail());

            user = (User) query.getSingleResult();
            String newPassword = randPass.getPass(8);
            user.setPassword(newPassword);
            entityManager.flush();
            renderer.render("/email/password.xhtml");  //Oh oh, nothing has been updated!!!
    }
}


Example 2:
@Name("registrationBean")
@Scope(ScopeType.CONVERSATION)
public class RegistrationBean implements Serializable {
    @In
    private EntityManager entityManager;

    @In @Out
    private User user;

    @In
    private Renderer renderer;

    @In //Ostermiller random password utility
    private RandPass randPass;

    @Transactional
    public void resetPassword() {
        Query query = entityManager.createQuery("SELECT u from User u where UPPER(u.email) = UPPER(:email)");
        query.setParameter("email", user.getEmail());

            User dbUser = (User) query.getSingleResult();
            String newPassword = randPass.getPass(8);
            dbUser.setPassword(newPassword);
            user.setFirstName(dbUser.getFirstName());     //kludge
            user.setLastName(dbUser.getLastName());    //kludge
            user.setPassword(newPassword);          //kludge
            entityManager.flush();
        renderer.render("/email/password.xhtml");
    }
}

Example 3 (My proposition) :

@Name("registrationBean")
@Scope(ScopeType.CONVERSATION)
public class RegistrationBean implements Serializable {
    @In
    private EntityManager entityManager;

    @In @Out
    private User user;

    @In //Ostermiller random password utility
    private RandPass randPass;

    @Transactional
    public void resetPassword() {
        Query query = entityManager.createQuery("SELECT u from User u where UPPER(u.email) = UPPER(:email)");
        query.setParameter("email", user.getEmail());

            user = (User) query.getSingleResult();
            user.setPassword(randPass.getPass(8));
            entityManager.flush();
            //NOTICE I TOOK OUT renderer.render("/email/password.xhtml")
    }
}

Why did I take out renderer.render from the code?  Because in pages.xml then we can make use of the render element to do the emailing, 
.....
 <page view-id="/registration/register.xhtml">
        <begin-conversation join="true"/>
        <navigation from-action="#{registrationBean.resetPassword}">
              <render view-id="/email/password.xhtml"/>  <!--Send one or more emails -->
              <render view-id="/registration/register.xhtml"/>  <!--I want to stay on the same page, or I could redirect, etc. -->
              <end-conversation/>
        </navigation>
  </page>
....


If you try it out now currently, this works except that it doesn't follow through.  What Seam does currently is that it renders /email/password.xhtml and stops.  What I am proposing that <render> elements follow through until the last render or redirect element.  

The advantages are highly numerous, one is as developers we would no longer need to be concerned about including renderer calls in our unit and non-page integration tests.  We uncouple the view (emails, and pages) from the controller -- huge win.  Another bigger advantage is that we can treat emails around a method as an AOP, we can easily add, remove emails based on the outcome of methods without us having to fidget with our code and have to test and retest our code.  See example 4.

Example 4 (My proposition) :

@Name("registrationBean")
@Scope(ScopeType.CONVERSATION)
public class RegistrationBean implements Serializable {
    @In
    private EntityManager entityManager;

    @In @Out
    private User user;

    @In //Ostermiller random password utility
    private RandPass randPass;

    @Transactional
    public String resetPassword() {
        Query query = entityManager.createQuery("SELECT u from User u where UPPER(u.email) = UPPER(:email)");
        query.setParameter("email", user.getEmail());
         try {
            user = (User) query.getSingleResult();
            user.setPassword(randPass.getPass(8));
            entityManager.flush();
            return "success"
         } catch (NoResultException nre) {
            return "noresult" 
         }
    }
}

.....
 <page view-id="/registration/register.xhtml">
        <begin-conversation join="true"/>
        <navigation from-action="#{registrationBean.resetPassword}">
              <rule if-outcome="success">
                 <render view-id="/email/password.xhtml"/>  <!--Send one or more emails --> 
                 <redirect view-id="/index.xhtml"/>
                 <end-conversation/>
              </rule>
        </navigation>
  </page>
....

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list