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.

JBoss Seam

JBoss Seam is a web application framework for Java EE 5, developed by JBoss. It uses two proven Java frameworks: EJB3 and JSF, by using these you can easily access any back-end EJB component from the front-end by addressing it by its Seam component name. Seam introduces the concept ofcontexts. Each seam component exists within a context. The conversation context for example captures all actions of a user until he logs out or closes the browser - even multiple uses of the browser back-button. You can automatically generate a CRUD (create-read-update-delete) web application from an existing database using seam-gen, a command line tool. Seam unifies the component models of JSF and EJB3, eliminating glue code, and letting the developer think about the business problem. Seam supports two open source JSF-based AJAX solutions: ICEfaces and Ajax4JSF. These solutions let you add AJAX capability to your user interface without the need to write any JavaScript code. Seam also provides a built-in JavaScript remoting layer for EJB3 components. AJAX clients can easily call server-side components and subscribe to JMS topics, without the need for an intermediate action layer. Neither of these approaches would work well, were it not for Seam's built-in concurrency and state management, which ensures that many concurrent fine-grained, asynchronous AJAX requests are handled safely and efficiently on the server side.

Tuesday, October 28, 2008

Java Generics

Java Generics
The Java Generics started with a trivial example implying a container type. The example below is from that category of examples. It's simple routine creates a LinkedList collection and displays the collection's first element:
1: import java.util.List;
2: import java.util.LinkedList;

3: class GenericsTest {
4: public static void main(String[] args) {
5: List floatList=new LinkedList();
6: floatList.add(new Float(4.5));
7: floatList.add(new Float(1.5));
8: Float nr=(Float)(floatList.iterator().next());
9:
10: System.out.println("First float number: "+nr);
11: }
12: }
This is a correct example--meaning, it will compile and run perfectly and will display the first element of the floatList list. But let’s modify it by replacing the line 9:
9: String str=(String)(floatList.iterator().next());
With this modification, the example code will compile without errors, but will not run correctly. Instead, it throws ajava.lang.ClassCastException exception. The exception is fully covered because you cannot cast a Float to a String!
Now you have a dilemma, because it's obvious that the casts from lines 8 and 9 are annoying. Firstly, you know what types of objects you have stored in the list, so why should you write an explicit cast when accessing the list s elements? Secondly, when you accidentally/intentionally mistake the cast type, why you do not get a compile-time error or at least a warning about this problem? Both questions have the same answer: Because Java Collection classes internally treat elements in the collection as Objects.
This problem is responsible for the birth of the Java Generics core idea, which goed like this: What if a developer could indicate the particular data type to be stored in a list? The practical application of this theoretical concept is to use angle brackets, shown in line 5 in the below example (which is the Java Generics version of the previous code):
1: import java.util.List;
2: import java.util.LinkedList;

3: class GenericsTest {
4: public static void main(String[] args) {
5: List floatList = new LinkedList();
6: floatList.add(new Float(4.5));
7: floatList.add(new Float(1.5));
8: Float nr=floatList.iterator().next();
9:
10: System.out.println("First float number: "+nr);
11: }
12: }
Now, your list is a list of Floats—you have specified this by explicitly placing the indicator at line 5. Thanks to this important modification, you no longer need the explicit cast from line 8; in this case, the List is a generic interface that accepts a type parameter, which, in this example, is Float. In any case, using the cast from line 8 in these conditions is not an error, it's an unjustified action.
Now, modify the example by replacing line 9:
9: String str=(String)(floatList.iterator().next());
The example will no longer compile successfully and a very explicit inconvertible types error will be reported. Cool!

Java Generics and Subtyping
Subtyping is a delicate Generics aspect, which may have a start point in the below example:
1: import java.util.List;
2: import java.util.LinkedList;
3:
4: class GenericsSubtype {
5: public static void main(String[] args) {
6:
7: List<Integer> numbers = new LinkedList<Integer>();
8: List<object> objects = numbers;
9: }
10: }

As you can see, line 7 creates a List of Integer using Java Generics. Looking at line 8, you
an probably extrapolate
the key question of Java Generics subtyping: Is a List of Integer a List of Object? In other words, is a collection of A a collection of B?
Most of the time, the answer is yes—but your compiler will disagree. The compiler knows allowing this code to pass will most likely result in
a List containing elements that are not String, down the road. Furthering this example, you will come across a very important rule—and one
that's worth remembering for future sections: If you have X(sub class or sub interface), a subtype of Y, and a generic type declaration (Z), then Z it
is not a subtype of Z.

Wildcards
Wildcards increase Java Generics' flexibility because they permit bounds on the type
of parameters and save you when you dont have specific knoweledge of a type parameter's value. To demonstrate, suppose you want to create a method that displays the elements of a collection. Without Java Generics, your method might look like following example (thedisplayCollection method).

import java.util.List;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Iterator;
public class TestCollectionWithoutGenerics {
static void displayCollection(Collection collection) {
Iterator iterator = collection.iterator();
for (int i = 0; i <>
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
List floatList = new LinkedList();
floatList.add(new Float(4.5));
List stringList = new LinkedList();
stringList.add(new String("string"));
displayCollection(floatList);
displayCollection(stringList);
}
}

Notice how you call the displayCollection method to display a collection of floats and a collection of strings.
Now, rewrite above example using Java Generics—but without wildcards looks like following.
Listing 1#
import java.util.List;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Iterator;

class TestCollectionWithGenericsWithoutWildcards {
static void displayCollection(Collection<Object> collection) {
for (Object obj : collection)
{ System.out.println(obj); }
}
public static void main(String[] args) {
List<Float> floatList = new LinkedList<Float>();
floatList.add(new Float(4.5));
List<String> stringList = new LinkedList<String>();
stringList.add(new String("string"));
displayCollection(floatList);
displayCollection(stringList);
}
}

Now, you have a serious problem, because above example compiles with errors! Why?! Because Object is not the supertype of all kind of collections
(as you already know from the previous section). This is where wildcards solve the problem.

By using a question mark between angle brackets ("?"), instead of Object type, you provide the real supertype of all kind of collections,
which is Collection<?>. This may sound like a minor change, but it is so important that it deserves showing the entire code again looks like following.

Listing 2#
import java.util.List;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Iterator;

class TestCollectionWithGenericsAndWildcards {

static void displayCollection(Collection<?> collection) {
for (Object obj : collection)
{ System.out.println(obj); }
}
public static void main(String[] args) {
List<Float> floatList = new LinkedList<Float>();
floatList.add(new Float(4.5));
List<String> stringList = new LinkedList<String>();
stringList.add(new String("string"));
displayCollection(floatList);
displayCollection(stringList);
}
}

Note: The Collection<?> formula is known as the collection of unknown and it supports elements of any type.
Now it's time to see how to include bounds in wildcards. First, there are two kinds of bounds:

Upper Bound:
When a wildcard includes an upper bound, the generic type is a subtype of the bounding class.
An upper bound is marked by the extends keyword, as you can see in the below prototype which is one of the ArrayList’s constructors:
public ArrayList(Collection<? extends E> c)

Lower Bound:
When a wildcard includes a lower bound, the generic type is a super-type of the bounding class.
Keep in mind that the super-type relation is reflexive. A lower bound is marked by the super keyword, as you can see in the below prototype,
which is the comparator method of the SortedSet class:
Comparator<? super E> comparator()

For a concrete demonstration, suppose you have the following abstract class:

public abstract class AbstractCar {
public abstract void carInfo();
}

Suppose also that you have the following subclasses:

public class LoganCar extends AbstractCar {
public void carInfo(){
System.out.println("-- Logan Info --");
}
}

public class SanderoCar extends AbstractCar {
public void carInfo(){
System.out.println("-- Sandero Info --");
}
}

Now, imagine that you have a list of AbstractCar objects and you want to display the information about every car.
At first, you'd probably implement something like Listing 2.

Everything seems fine, but a closer look will reveal a big problem with your application.
What happens if you have a collection of LoganCar or SanderoCar, not a collection of AbstractCar?
Obviously, the application will not pass compile-time because of what you learned in a previous section.
To fix this, you can use an upper bound to indicate that the showInfo method can be called with a collection of AbstractCar
and any other subtype of AbstractCar, like LoganCar or SanderoCar. following example shows the application again.

import java.util.List;
import java.util.LinkedList;

public class showCarsInfoWildcard {

public static void showInfo(List<? extends AbstractCar> cars){
for (AbstractCar car : cars)
{ car.carInfo(); }
}

public static void main(String[] args){

LoganCar logan_1 = new LoganCar();
LoganCar logan_2 = new LoganCar();
List<LoganCar> mycars = new LinkedList<LoganCar>();
mycars.add(logan_1);
mycars.add(logan_1);
showInfo(mycars);
}
}