I am guessing this has been discussed before but I can't figure a way to search for it so my apologies if this has already been covered.

Basically, what I need is to keep certain variables in a scope that is session-wide, but on a per-browser-window/tab basis. In other words a setting that will remain with any browser page until reset by the user on that page. Other views open by the user should not be affected by changes on another window.

In past projects, we have handled this using Tomahawk's t:saveState (which is embedded in every page in the application), but I am hoping that there is a Seam-specific solution.

I have not looked much into nested conversations, but my gut feeling is that that is going to add a lot of complexity. I will have several individual conversations specifically for handling various user transactions, yet there will be a few attributes I want to share basically across the session (yet not across browser windows.) I can add a conversation to handle this, but then must deal with all my other conversations as nested conversations -- right?

I didn't mention nested conversations... I wrote long running conversations

but my gut feeling is that that is going to add a lot of complexity.

I agree about nested conversations adding complexity, but... I thought you wanted the same value every time from every request that originated from the same browser window and for that you do not need nested conversations, good old long running conversations are good enough.

I will have several individual conversations specifically for handling various user transactions, yet there will be a few attributes I want to share basically across the session (yet not across browser windows.)

Well you can use ScopeType.SESSION for those few attributes you want to share basically across the session (still no need for nested conversations)

Now if you want to share them across the session (yet not across browser windows.)... First thing that comes to my mind is that is a contradiction... scopes go from more general to specific ScopeType.APPLICATION -> ScopeType.SESSION -> ScopeType.CONVERSATION -> ScopeType.PAGE (there are other scope types but they follow that basic rule) so, either you want somethig to be shared for all the browser windows inside the same session (ScopeType.SESSION) , or you want something fora particular window (ScopeType.CONVERSATION) or for a particular page (ScopeType.PAGE), I just do not see how something could be shared them across the session (yet not across browser windows.)

I can add a conversation to handle this, but then must deal with all my other conversations as nested conversations -- right?

Perhaps (If what you need is smaller conversations inside a long running conversation across many pages... because if it is going to be in the same page you can use ScopeType.PAGE) , I would have to be more familiarized with the effect you want to achieve... one thing is for sure, I can not think of an easier way to do this without Seam ScopeTypes (with or without nested conversations). Of course you can reinvent ScopeTypes, but I bet using what seam provides for this will a much better idea (and specially easier to implement).

Another options is to build your UI like a RIA, with all this nested conversations coming and going as javascript functions, and essentially building a heavy client with javascript (I feel that is where everything will end sooner or later when we realize that all RIAs are doing is bringing back the heavy client) (Welcome back Swing!)

1) User logs in and enters a part of the application where he needs to select a portfolio -- he has multiple choices, and every screen (or many screens anyway) hereafter will make use of the currently selected portfolio.

2) User goes to the projects page, which lists all projects for said portfolio. He selects one to edit. (At this point I start a conversation which will be used over a number of pages to manage his edit session).

3) User can either complete the edit session or perhaps may exit using the menu -- in the menu all the links are s:link with propagation none btw.

4) User does various other activities, most of which use conversations.

5) At some point user opens another browser window, and selects a different portfolio -- because perhaps he wants to retrieve some information from that portfolio while editing the first, and would like to cut and paste or view screens side by side or whatever.

6) Back in the original window, the user should still have that original portfolio value as the current portfolio for that window.

Now, then, is using nested conversations the only way to handle this use case?

1) User logs in and enters a part of the application where he needs to select a portfolio -- he has multiple choices, and every screen (or many screens anyway) hereafter will make use of the currently selected portfolio.

If it is true that hereafter will make use of the currently selected portfolio and only the selected portafolio the SESSION should be enough.

2) User goes to the projects page, which lists all projects for said portfolio. He selects one to edit. (At this point I start a conversation which will be used over a number of pages to manage his edit session).

Right, conversation is a good idea for this. (IMO)

3) User can either complete the edit session or perhaps may exit using the menu -- in the menu all the links are s:link with propagation none btw.

I have had some performance problems with s:link in menus when the .page.xml have many of parameter references <param name="" value="#{}", so I prefer to use h:outputlink.

4) User does various other activities, most of which use conversations.

Well, if those are of a smaller scope, I guess you will have to use nested conversations after all (or you may use parallel conversations)

5) At some point user opens another browser window, and selects a different portfolio -- because perhaps he wants to retrieve some information from that portfolio while editing the first, and would like to cut and paste or view screens side by side or whatever.

Well that means it is not true that hereafter will make use of the currently selected portfolio and only the selected portafolio and therefore you will have to use CONVERSATION for that (and that means you will need NESTED for subsequent operations (in this case projects) on the selected portfolio)

6) Back in the original window, the user should still have that original portfolio value as the current portfolio for that window.

But, not only for that window, also for any window called by that window... and any window with that exact same url? don't you agree?

I think here you might have a conceptual problem, it is not right (from a server perspective) to say that something happens for that window, but you can say that it happens for that url o for that conversation id... unless, as I said in the previous post, you are building a RIA and then, since all interaction is handled in javascript, you may only need CONVERSATION for the moment when you select the portfolio (or perhaps not even than, nothing prevents you from building portfolio browser -all in javascript- on the same window), and after that, all operations done for a particular conversations are handled in the client

Now, then, is using nested conversations the only way to handle this use case?

The way I see it you have 2 options, if you want to make the server aware of what is going on, then you have to use conversations, or, you can build this as a RIA using something like... i don't know, ExtJS o Flex and do all this conversational handling on the client.

and thats *it*. Now every single piece of code in the application can pull userctx out of FacesContext and use it to store/retrieve configuration information.

I have not figured out a way to duplicate this in Seam using PAGE scope. I can of course create a bean object that Injects and Outjects "userctx", but unless that bean is actually used during a user transaction, the Injection/Outjection will not happen and thus the value will be lost. (Or is there an easy way you can think of to force the injection/outjection on every single user transaction?)

I have not actually tried it, no, but I believe it will not work, because as soon as there is any transaction that does not explicitly use userctx, it will not be created/outjected into the next Page scope, and therefore will never be available again for any subsequent transaction that does need it (except of course it would be auto-created, though that does not help because it will have lost any values previously stored in it.)

but I believe it will not work, because as soon as there is any transaction that does not explicitly use userctx, it will not be created/outjected into the next Page scope, and therefore will never be available again for any subsequent transaction that does need it (except of course it would be auto-created, though that does not help because it will have lost any values previously stored in it.)

I don't quite get what do you mean by transaction... and why would you want to have it outjected into the next Page scope (AFAIK pages scopes are for stuff in the same page, no in the next page, and that (I think) should be true for both Tomahawk and Seam)

Do I misunderstand how the Seam life cycle works?

Thanks,ken

I have to admit I don't like when someone else post this as an answer to one of my questions but in this case I think: you should really try and see.

A user transaction is any single unit of work that a user executes via a single http request. Every link click or form submission in the application is a user transaction.

Not to be confused in any way with a persistence transaction.

The reason I need this to follow up in the next page scope is that I would be using this page scope trick to pass a variable value from page to page to page forever, thereby placing the users current selection as available to any downstream code, even if it is 100 user transactions down the road. The nice thing about using said trick is that when the user opens a second browser window and changes his selection, it cannot affect the original browser window.

Or at least that is how I used t:saveState (and it has worked quite well.) Note one drawback I'd like to fix is that we could never redirect as the variable in the request scope is lost in doing so.

I am not yet ready to try this because I am still relatively sure that even though everything will work great going from A to B (really I do believe this), when the user then goes from B to C and there is no explicit use of userctx, then any values in userctx will be gone.

The difference between savestate and Seam Page scope is that in the former, it goes from embedded in the page to into the request scope and then back out embedded in the next page. Whereas in Seam, the value will be outjected only if something specifically outjects it -- and I would prefer not to have to go into every single action class and write an Inject/Outject userctx, which it seems to me would be the only way to get this to work.

However, I do have a hope that there is some trick I could use to do this. I am afraid that the inability to redirect is going to be too restrictive for Seam (plus I just generally would prefer to find a Seam solution.)

Quick update -- I did try this since it was easy enough to do, and I can confirm that it worked as I expected. The userctx value does not survive past a user transaction in which the underlying action class does not inject the userctx bean.