4 Replies Latest reply on Nov 12, 2006 3:39 PM by Gavin King

    Abstract components, EL and auto-instantiation

    Jye Tucker Newbie

      I have an abstract User class and subclasses for different types of users in the system.

      I would like Seam to manage a "currentUser" component which I put into session context after login. I would ideally annotate the abstract User class with @Name("currentUser") so whatever User subclass was being used could still be bijected this way.

      I want to test the existence of the currentUser in EL with #{empty currentUser} but SeamVariableResolver always tries to create it - resulting in an InstantiationException due to the User class being abstract.

      So effectively what I want is the ability to reference the EL variable without the SeamVariableResolver trying to auto-instantiate it.

      Or am I missing an obvious alternative?

        • 1. Re: Abstract components, EL and auto-instantiation
          Pete Muir Master

          I would suggest using a manager component:

          @Name("currentUser")
          @Scope(SESSION)
          @Stateful
          public class CurrentUserManagerBean implements CurrentUserManager {
          
           private User currentUser;
          
           @Create
           public void create() {
           // Initialise the user e.g. get username from JAAS, load user from Persistence Context
           currentUser = ...;
           }
          
           @Unwrap
           public User unwrap() {
           return currentUser;
           }
          
          }


          Alternatively you could make the manager stateful and do all the work in @Unwrap,

          @Name("currentUser")
          @Stateless
          public class CurrentUserManagerBean implements CurrentUserManager {
          
           @Unwrap
           public User unwrap() {
           // Initialise the user e.g. get username from JAAS, load user from Persistence Context
           User currentUser = em.find(User.class, username);
           return currentUser;
           }
          
          }



          or implement a @Factory manager pattern.


          @Name("currentUserManager")
          @Stateless
          public class CurrentUserManagerBean implements CurrentUserManager {
          
           @Factory("currentUser")
           public User unwrap() {
           // Initialise the user e.g. get username from JAAS, load user from Persistence Context
           User currentUser = em.find(User.class, username);
           return currentUser;
           }
          
          }


          • 2. Re: Abstract components, EL and auto-instantiation
            Jye Tucker Newbie

            Nice suggestion Pete. Looks like it'll work great.

            Thanks.

            • 3. Re: Abstract components, EL and auto-instantiation
              Jye Tucker Newbie

              For anyone else reading this - use the @Factory method.

              @Unwrap has problems with ClassCastException's since the unwrapped object is a different class to the component.

              • 4. Re: Abstract components, EL and auto-instantiation
                Gavin King Master

                 

                @Unwrap has problems with ClassCastException's since the unwrapped object is a different class to the component.


                What do you mean? Pete's code was perfectly correct.