Pete and I had a chat on this a few days ago, and here's the
summary
on how we decided to go, and what I've implemented in the patch at
https://jira.jboss.org/jira/browse/JBSEAM-3645
Seam doesn't have any notion of choosing components based on request
specifics, so rather than having the Manager and StatusMessages
component subclasses install themselves based on class dependencies,
we'll have the base classes unwrap themselves as the
view-layer-dependent subclasses per-request, by asking the subclasses
if they want to participate in the request. The subclasses register
with the parent class at startup. See the above issue for more
details.
Also, the WicketRedirectFilter will co-exist with, rather than
replace, the jsf RedirectFilter, and each will turn on/off based on
whether the requests is specific to that view layer.
As an aside, I do think that it would be worth, in the long run,
having a mechanism to choose components to instantiate by annotating a
component method that would let the context ask the component whether
it wishes to be used. Right now, if you need to contextually choose a
component to install from a set of components, you have to have a
@Factory or an @Unwrap which knows about all the possible
implementations, which isn't always possible or even desired.
I think the correct approach here to allow implementations to register
themselves programatically. I don't want to add some magic annotation.
The
mechanism I used in the above patch is slightly contorted. What I'd
like to be able to do is:
@In StatusMessages statusMessages;
...
@Name("facesMessages")
public class FacesMessages extends StatusMessages {
@RoleSelector("statusMessages")
public boolean shouldIbeInstalled() {
return FacesContext.getCurrentInstance() != null;
}
...
}
@Name("wicketMessages")
public class WicketMessages extends StatusMessages {
@RoleSelector("statusMessages")
public boolean shouldIbeInstalled() {
return Application.exists(); //ask wicket's threadlocal-aware code
}
...
}
and then have Component.getInstance() do the work for me, throwing an
exception if two components simultaneously volunteer for a role, or
perhaps provide a precedence mechanism for resolution of conflicts a
la @Install.
-Clint
On Thu, Oct 23, 2008 at 5:57 PM, Clint Popetz <cpopetz(a)gmail.com>
wrote:
> On Fri, Oct 17, 2008 at 1:59 PM, Clint Popetz <cpopetz(a)gmail.com>
> wrote:
>
>> * Fixes to make it possible for jsf, wicket, and other web tier
>> components
>> (i.e. struts, using ContextFilter) to co-exist in the same
>> deployment, which
>
> Per Pete's suggestion, I'm starting a discussion on how to do this.
>
> There are four classes that currently prevent this from working:
>
> * WicketRedirectFilter and WicketExceptionFilter
>
> These exist mainly to turn off those two filters for wicket requests.
> I suggest that these can be deleted, and wicket users can just do:
>
> <web:redirect-filter url-pattern="*.seam"/>
> <web:exception-filter url-pattern="*.seam"/>
>
> so that the filters are only enabled for faces-specific requests.
> That violates DRY, because they have to change that if they change
> web.xml's mapping of the faces servlet. But I know of no good way
> from a filter to figure out at runtime how the faces servlet is
> mapped.
>
> * WicketStatusMessages and WicketManager
>
> These are more difficult. The hack I did, which works, is to have
> each extend the faces variants of these classes, and to have each
> short-circuit the direct super class behavior when
> org.apache.wicket.Application..exists() returns true, i.e. when
> wicket
> has decided it owns the request. But that's ugly, and wouldn't be
> sustainable as more view layer options are added.
>
> FacesManager really shouldn't subclass Manager, in my opinion. It
> overrides hardly any methods, and the ones it does override only
> exist
> in the base class for the benefit of other code which could directly
> call FacesManager, because it is already faces-aware. I made a stab
> at seeing what it would take to refactor this to make Manager a
> view-layer-agnostic component. It's possible, and not even that
> hard,
> but the main problem are redirects. Currently a lot of code tells
> the
> conversation (or conversation entry) to redirect(), and they both
> store a jsf view id and then ask the manager to redirect to that id.
> Since there is only one manager, that manager has to be faces aware.
>
> We could instead have conversation subclasses for each view
> technology, i.e. FacesConversation, and FacesConversationEntry, and
> create the right one with factories, and have each know how to
> redirect, or know which component (FacesManager) to ask to redirect.
> But then we come to the question of "should conversations themselves
> be view-agnostic," e.g. should it be possible to move from a
> wicket-based page to a jsf based page while maintaining the same
> conversation. I think so. But that would mean a fair amount of
> work,
> because it means having conversations have two components, a
> view-agnostic part and a view-centric part, with each delegating to
> the other.
>
> At this point, I feel like I might be treading into deep waters, and
> so I'm interested in whether this type of work, to make the core of
> seam less dependent on JSF, is a direction you'd like to see the
> source go. I don't think it can be done without breaking a fair
> amount of code, and who knows how much code has EL expressions that
> reference these components, i.e. to do conversation-switching from
> JSF. (Ironically, untyped EL expressions breaking due to
> refactoring
> is the main reason I'm switching from JSF to wicket :)
>
> Thanks for listening, and interested in your thoughts.
>
> -Clint
>
_______________________________________________
seam-dev mailing list
seam-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/seam-dev