Saturday, February 27, 2010

Seam Contexts

Seam Contexts


Most of the web based applications use tradetional contexts (Request, Sesssion, ServletContext and end up with writing lots of code base to maintain the state. Some times developers need to store instances in Session Context though they need not to be in Session context for the whole User’s Session. That’s where Seam comes in, Go on..


One of the most exciting features of JBoss Seam is the contextual component model that radically changes the way we design applications. It has become so important, it is now part of the JEE6 specification through the JSR-299.


You may already be familiar with the request, session and application scopes of the Servlet specification. They are very useful to save and retrieve data but they have a huge limitation: you can only access them from a Servlet/JSP.

JBoss Seam overcomes this limitation by making the scopes (called contexts in Seam) available to the whole application instead of only to Servlets/JSP’s. So, you’ll find request(event)session and application contexts and 3 more they’ve created: pageconversation and business process contexts.

The request(event), session and application contexts work exactly as they do in Servlets/JSP’s so I’ll just skip their explanation. I will, however, explain briefly the pageconversation and business process contexts.

Page Context
The page context is broader than the request context as it spans multiple requests over the same page. This is very useful if you need to make roundtrips to the server to perform validation, bring information, etc. while maintaining the same page state.

Conversation Context
The conversation context is broader than the page context as it can expand to multiple request and pages but narrower than the session context. It is very useful to implement wizards-like interfaces in which the user has to fill data across multiple pages while maintaining the state over the whole process. You control the creation and destruction of each conversation.

Business Process Context
As it name implies, it is used to maintain state information during the execution of a business process instance in jBPM.

Using contexts from your code
You can use the Contexts class to gain access to one of the contexts, defined by the Context interface, and then use theset or get methods to save or retrieve information respectively.
Each Context will be bind to a ThreadLocal, so you can access them using set and get methods of ThreadLocal as usual

Contexts Class code snippet
static final ThreadLocal<context> applicationContext = new ThreadLocal<context>();
static final ThreadLocal<context> methodContext = new ThreadLocal<context();
static final ThreadLocal<context> eventContext = new ThreadLocal<context>();
static final ThreadLocal<context> pageContext = new ThreadLocal<context>();
static final ThreadLocal<context> sessionContext = new ThreadLocal<context>();
static final ThreadLocal<context> conversationContext = new ThreadLocal<context>();
static final ThreadLocal<context> businessProcessContext = new ThreadLocal<context>();

For example, to save the current user information in the session context you use the following code:
User user = new User();
Contexts.getSessionContext().set("user", user);
Then, when you need to retrieve the user information, you use:
User user = (User)Contexts.getSessionContext().get("user");
Really simple, ah? You can also use the @Out and @In annotations in class attributes to save and retrieve information:
@Out(value="user",scope=ScopeType.SESSION)
User user;
What the @Out annotation is telling Seam is to save the User object in the Session context with the key “user”. Then, you can retrieve the user with the following code:
@In(value="user",scope=ScopeType.SESSION);
User user;
Again, the @In attribute is telling Seam to inject the User object from the Session context saved with the “user” key. You don’t have to write any getters or setters in your class, Seam will just outject or inject the information whenever an @Out or @In annotation is present. If no object is found under the “user” key, null will be injected.
As you can see, the value attribute of the @In and @Out annotations are used as a key for searching or saving data in the contexts. The scope attribute is used to specify the context in which the value should be injected or outjected. This attributes are optional; so, what happens if we don’t specify them as in the following example?
@In
When you don’t specify the value attribute, Seam uses the attribute’s name as key by default. In the preceding code fragment, Seam will use “name” as the key for the @In annotation and “user” for the @Out annotation.
If you don’t specify the scope of an @In annotation, Seam will scan all the contexts in the following order: eventpage,conversationsessionbusiness process and application. If the key is not found, it will inject null. You can use this feature programmatically by calling the Contexts.lookupInStatefulContexts() method.
If you don’t specify the scope of an @Out annotation … well, as the @Out JavaDoc states: “If no scope is explicitly specified, the default scope depends upon whether the value is an instance of a Seam component. If it is, the component scope is used. Otherwise, the scope of the component with the @Out attribute is used.” I know, I haven’t talked anything about Seam components as it is not the topic of this article. I probably post my next topic on Seam Componet model.

No comments: