[seam-dev] jsf in seam 3

Clint Popetz cpopetz at gmail.com
Wed May 27 09:16:08 EDT 2009


On Tue, May 26, 2009 at 11:59 PM, Dan Allen <dan.j.allen at gmail.com> wrote:

>
> What I realized is that StatusMessages are really a generic repository that
> should be updated and consumed by the framework-specific activity.
> Therefore, it seems to me like there should be one and only one
> conversation-scoped StatusMessages. Then, if you want to have some extra
> methods for convenience (for instance in JSF to add a StatusMessage from an
> existing FacesMessage) you create a class which extends and wraps the
> StatusMessages component (StatusMessages would be injected into it and all
> overrides delegating to it). You could also override the onBeforeRender()
> method where you might put the logic for converting and transfering to the
> native message type and storage. The executor of that conversion would be
> implemented in the framework-specific listener.
>
> For instance, 9 out of 10 times you simply inject the StatusMessages to use
> in your application:
>
> @Current StatusMessages statusMessages;
>
> For JSF, there is a FacesMessages bean which inherits from StatusMessages
> (to keep the API the same) and delegates calls to the StatusMessages
> instance. It also adds the logic to create FacesMessage objects in the
> onBeforeRender() method
>
> public void onBeforeRender() {
>     super.onBeforeRender();
>     // create FacesMessage objects and register them here
> }
>
> The ConvertStatusMessagesListener (a JSF system event listener) executes
> the onBeforeRender() call.
>
> manager.getInstanceByType(StatusMessages.class, new
> AnnotationLiteral<Faces>() {}).onBeforeRender();
>
> There are also some convenience methods on the FacesMessages instance. If
> you want to use them, you inject as follows:
>
> @Faces FacesMessages facesMessages;
>
> I can't use @Current here because otherwise the resolution would be
> ambigous. I could just clone the StatusMessages API in the FacesMessages
> class to avoid having to use this binding type, so if you have a
> feeling/advice there, I would be glad to here it.
>

This approach seems fine to me, but I also wonder if composition might be
better than inheritance in this case, i.e. StatusMessages is framework
independent and not specialized, and provide a separate component subclassed
by each framework that propagates the contents of StatusMessages into the
view.   Most code that injects StatusMessages only wants to add to it
messages to it, and the only code that wants to render those messages is in
the view framework glue, so they seem like separate concerns.  The only
reason I didn't go this route in my mods to Seam2 was to minimize changes
for backward compatibility.


>
> Okay, that's one approach. Now for something different. There is a similar
> specialization w/ the Expressions class (an EL convenience API). If working
> within the JSF request, we want to override some methods so that the bean
> uses the current JSF EL context. In this case, I decided to try Clint's
> approach described in the cited issue report.


That approach also looks fine to me, although I should note that with regard
to your specific example, Wicket has no notion of Expressions, and so
wouldn't specialize it.  Wicketeers don't go for EL, as we have nothing that
isn't in java :)

Now that s/Manager/BeanManager/ is view agnostic, and once StatusMessages is
refactored as above, I'm not sure there's a use case for the
RuntimeSelectedBean mechanism.  Well, yet :)

-Clint



> A producer method will locate beans that have the binding type
> @RuntimeSelected and will consult the isActive() method to determine which
> one is prepared to handle the current request. The isActive() method comes
> from the RuntimeSelectedBean interface. So the bean must have both the
> binding type and the interface. There is a second binding type, @Default,
> which indicates which implementation should be used when there are no
> @RuntimeSelected implementations present or active. It is mutually exclusive
> with @RuntimeSelected.
>
> So you have:
> public @Default class Expressions { ... }
> public @RuntimeSelected class FacesExpressions extends Expressions,
> RuntimeSelectedBean {
>     public boolean isActive()
>     {
>         return FacesContext.getCurrentInstance() != null;
>     }
> }
>
> public @RuntimeSelected class WicketExpressions extends Expressions,
> RuntimeSelectedBean {
>     public boolean isActive()
>     {
>         return Application.exists();
>     }
> }
>
> The producer type for the Expressions bean is application-scoped and the
> producer method is dependent-scoped (or request-scoped?). The available
> instances are looked up when the producer is initialized and the instance is
> selected from this set each time the producer is resolved.
>
> Of course, I could have used this strategy for the StatusMessages too,
> except in the case of StatusMessages it is logical to use the shared/generic
> StatusMessages bean. It's only when you need to convert the messages do you
> need the specialization and therefore I think we can avoid having to do the
> runtime selection.
>
> I've committed all of this to the Seam trunk if you want to check it out.
> I'm open to suggestions...I'm just trying to get used WB and find a workable
> approach. The solutions we decide on are important because the define a
> standard practice we will follow as more cases arise.
>
>
> -Dan
>
> --
> Dan Allen
> Senior Software Engineer, Red Hat | Author of Seam in Action
>
> http://mojavelinux.com
> http://mojavelinux.com/seaminaction
> http://in.relation.to/Bloggers/Dan
>
> NOTE: While I make a strong effort to keep up with my email on a daily
> basis, personal or other work matters can sometimes keep me away
> from my email. If you contact me, but don't hear back for more than a week,
> it is very likely that I am excessively backlogged or the message was
> caught in the spam filters.  Please don't hesitate to resend a message if
> you feel that it did not reach my attention.
>



-- 
Clint Popetz
http://42lines.net
Scalable Web Application Development
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/seam-dev/attachments/20090527/2d303ff1/attachment.html 


More information about the seam-dev mailing list