The Work Area Service


Passing information implicitly between application components is a useful idea. It allows you to identify information that has relevance across your application and passes it without having to call it explicitly as an argument to every method request. It also allows you to pass information through otherwise ignorant components.

Work area is a service provided by WebSphere for passing information implicitly on method requests. The principle behind work area is simple. You create a work area in one program (a J2EE client, servlet, or EJB) and fill it with few of application-defined properties. The work area represents a context within a work scope – you begin and end that work scope in your program with that context. The work area context, containing the properties that you set, is automatically and implicitly propagated on the downstream requests. The context is then instantiated in the context of the downstream component:

click to expand

Downstream components can get any number of the properties from the work area context. The work area context continues to be propagated further, on any methods invoked from the intermediate component. Thus, even if the intermediate component does not get any properties from the work area, the downstream components can still get work area information set by the top-most program.

Intermediate objects can extend the work area, adding their own properties, which will then be passed on to downstream components from there.

In some sense, you can think of work areas as contexts for holding global variables – global to the entire distributed system over which you will cascade work. The context is used to scope the variables contained within the work area.

About the Work Area Example

The example used in this section is composed of four parts:

  • WorkAreaClient – is a J2EE client that can be used to drive various operations in this example.

  • MidTierWA1 – is a poor choice of names to represent the First-Tier in the diagram above. It is used to create a Catalog work area context and to set the category and numberOfItems properties.

  • MidTierWA2 – represents the Mid-Tier in the diagram above. It creates a nested work area context in which it creates the season and promotionalEvent properties. Beyond that, the MidTierWA2 object is used to change, remove, and conflict with the protection mode attributes of the property settings created by MidTierWA1.

  • FinalTierWA – represents the Final-Tier in the above diagram and demonstrates the actual context received by that tier. It collects up its received context and returns it to the top of the request as an array of strings, which can then be printed by the WorkAreaClient for each of the tests that it is coded to perform.

To run the example, you should install the Chapter11Sample application in the application server, and then invoke the client from a command line. From a command prompt:

  • Make sure that <WAS_INSTALL_ROOT>/bin is in your path.

  • Invoke the following command:

     launchClient <WAS_INSTALL_ROOT>/installedapps/<nodename>/Chapter11Sample.ear               –CCjar=Chapter11SampleWorkAreaClient.jar 

You will need to substitute <WAS_INSTALL_ROOT> with the path to where you have installed WAS and <nodename> with the nodename you specified during installation (usually taken from your host name, by default).

Enabling the Work Area Service

The work area service is provided with the programming model extensions of the Enterprise edition of WAS. It is enabled by default, but can be disabled through the admin interface. To disable/enable the service through the user interface, you can turn to the Work Area Service property page of the application server on which your application will be hosted. In addition to enabling the service, you can also set the maximum send and receive size for work areas – the send size maximum will affect how much data is transmitted from your application server on downstream requests, the receive size maximum will affect how much data will be accepted from upstream requests. The truncation of information for these settings is arbitrary and brutal – potentially truncating property names and/or values. In addition, propagating work area context implicitly will have some effect on network traffic and performance and so you should always use the available work area context prudently:

click to expand

The Work Area Interfaces

The work area service is composed of a single interface, UserWorkArea, which extends java.io.Serializable, that represents the work area service. You will acquire the UserWorkArea object from JNDI. The UserWorkArea interface supports the following operations:

  • begin() – takes a string name identifying the work area context that you want to start.

  • complete() – terminates the last work area context opened within this component.

  • getName() – retrieves the name of the outstanding work area context.

  • retrieveAllKeys() – gets the names of all properties in the current work area context.

  • set() – creates or updates a property in the context. This operation is overloaded to allow you to optionally specify the protection mode for the property. Properties are created with the Normal protection mode by default. The set() method can throw a NoWorkArea, NotOriginator, or PropertyReadOnly exception if you attempt to set a property that has already been protected by an upstream owner of the work area, or if you have not created a work area context in which to set the property.

  • get() – returns the specified property, if it exists in the current context.

  • getMode() – returns the protection mode setting for the specified property.

  • remove() – removes the value of the specified property from the current context.

Getting Access to the Work Area Service

As with the internationalization service, you must get access to the work area service itself before you can do anything with work areas. You can get to the work area service from the JNDI name space with "java:comp/websphere/UserWorkArea":

 package websphere.pro.chapter11.sample.workarea; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.naming.*; import com.ibm.websphere.workarea.PropertyModeType; import com.ibm.websphere.workarea.UserWorkArea; /** * Bean implementation class for Enterprise Bean: MidTierWA1 */ public class MidTierWA1Bean implements javax.ejb.SessionBean {   private javax.ejb.SessionContext mySessionCtx;   private InitialContext jndi;   private UserWorkArea workArea;   /**   * ejbCreate   */   public void ejbCreate() throws javax.ejb.CreateException {     try {       jndi = new InitialContext();       workArea = (UserWorkArea)       jndi.lookup("java:comp/websphere/UserWorkArea");     } catch (NamingException e) {       System.out.println("Exception looking up Work Area service: " +                          e.toString());       e.printStackTrace();     }   } } 

You only have to get access to the service once, so this is usually done in your component's initialization routine. You should then cache a reference to the service and reuse it on any method request to your component. The service will always operate on the current context on the thread of execution.

Creating and Terminating Work Area Context

Work areas are created within a execution context that consists of the thread of execution and the specific bean in which the context is created – the context is created when you begin the work area and will remain in effect until you complete it explicitly on the current thread of execution, or until you return from the method where the context was created. Neither work area contexts, nor the changes that you make to them are propagated back upstream to the calling program. The following code demonstrates creating and terminating a work area context:

 public String[] createAndPassWorkArea() {   String[] waState = null;   try {     workArea.begin("Catalog");     waState = finalTierWA.getWAState();     workArea.complete();   } } 

You can specify the name of the work area context when you begin it. The name should be used to identify the context for debugging and tracing. Typically, you can use the name of the entity or the business function you are performing in which the context is created.

The previous code snippet shows beginning and completing the work in the same method. In fact, you can begin and complete the context in separate routines – as long as they are called in the same code path for the thread of execution. If you do not complete the work area context, it will be terminated automatically when the method in which it was created returns.

You can only complete a work area that you begin within your component. Work areas that you create in a component belong to that component on the thread of execution and are terminated when that component returns from executing its request. If you attempt to complete a work area belonging to another component, a com.ibm.websphere.workarea.NotOriginator exception will be thrown.

Setting Work Area Properties

Having a work area context is not very useful unless you have something to put in it. Adding values to the work area is a simple matter of setting properties. A common use of the work area is to place properties about the context in which a business service was requested – such as the type of device the user was using, which might, for example, indicate something about how much or what form of information should be produced for the request. In other cases, you might set the work area context with properties that describe special business conditions that you consider in other parts of your application – in particular, properties that you do not want to pass explicitly on previously designed interfaces. It is entirely up to you to establish an appropriate name convention for your properties – whatever you choose will be what other components will have to look for if they are to retrieve them later, downstream. The following snippet demonstrates setting properties in the work area context:

 workArea.set("category", "Trees"); workArea.set("numberOfItems", new Integer(12)); 

You can store any Java object type in the work area properties as long as the type implements the class java.io.Serializable.

Getting Work Area Properties

A downstream component can retrieve any work area properties passed to it. You do not have to begin a new work area context to retrieve the properties – you just get the property from the work area service:

 public String[] getWAState() {   String itemCategory = (String) workArea.get("category");   Integer totalItems = (Integer) workArea.get("numberOfItems");   String season = (String) workArea.get("season");   String event = (String) workArea.get("promotionalEvent"); } 

Obviously, you do not have to get all the properties contained in the work area. In fact, you do not have to get any of them. Regardless, getting a property does not remove the property from the work area context. The work area context will continue to be propagated further to downstream components.

Nested Work Areas

When a downstream component is invoked, the outstanding work area context is propagated on the request and is then available to the downstream component to access. However, the context really belongs to the upstream component. You cannot change the context that belongs to another component, so if you attempt to change or remove a property in the received component, a com.ibm.webphsere.workarea.NotOriginator exception will be thrown.

However, you can create your own work area context within the downstream component. The work area context that you create in the sub-component becomes nested within and inherits the upstream context. You can then create additional properties within the nested context. If you create a property with the same name as an existing property in the received context, you will override the original property value within your own context. The original context property is actually left untouched and will be restored when you complete your nested context:

click to expand

None of the changes you make will be returned back to the upstream component – you cannot communicate changes back to the calling component.

You create a nested work area context in the same way as you created the original context, that is, by beginning the context. Likewise, you can terminate the nested context by completing it, or it will be automatically terminated when you return from your method – even if you have not explicitly completed it. You do not name the context that you are terminating when you issue the complete operation, so the innermost (the most recently) created work area context is terminated.

Terminating the work area context is demonstrated in this snippet:

 workArea.begin("Catalog"); workArea.set("category", "Trees"); workArea.set("numberOfItems", new Integer(12)); waState = finalTierWA.getWAState(); workArea.complete(); 

Removing Work Area Properties

You can remove any of the properties that you create in your work area. As before, downstream components cannot remove the properties supplied by an upstream component, unless they do so within a nested work area. In other words, a downstream component can create a nested work area, and then remove the inherited property. Of course, this does not actually remove the property from the upstream context – it just renders the property invisible to further downstream components:

 workArea.remove("numberOfItems");  //removes numberOfItems from received context workArea.remove("season");         //removes season from nested context 

Protecting Work Area Properties

There may be cases where you want to introduce a property to the work area context and prevent downstream components from either changing the property value or even removing it. The work area service allows you to control this by setting a protection-mode attribute for any properties you introduce to your work area context. The following protection modes can be set for a work area property:

  • PropertModeType.normal – the downstream components can change or remove the property within their own nested context

  • PropertyModeType.fixed_normal – the downstream components can change the property value in their own nested context, but can not remove it

  • PropertyModeType.read_only – the downstream components can remove the property from their own nested context, but cannot change its value

  • PropertyModeType.fixed_readonly – the downstream components cannot remove nor change the property value, even in their own nested context

You can only set property modes at the time that you set the property. If you are in a downstream component and the received context allows you to set a passed property – that is, the received property has a property mode of either normal or fixed_normal – then you can set the property with a different mode of an equal or more constraining level. In other words:

  • If the received property has a mode of normal, then you can set the property with a mode of normal, read_only, fixed_readonly, or fixed_normal in your nested context.

  • If the received property has a mode of fixed_normal, then you can set the property with a mode of fixed_normal or fixed_readonly in your nested context.

  • If the received property has a mode of read_only or fixed_readonly, then you cannot set the property.

This allows you to even further constrain what downstream components can do to the property in their component. The following snippet demonstrates creating properties with various protection mode attributes:

 workArea.set("category", "Trees", PropertyModeType.normal); workArea.set("numberOfItems", new Integer(12), PropertyModeType.read_only); workArea.set("season", "Winter", PropertyModeType.fixed_normal); workArea.set("promotionalEvent", "Valentines Day",                     PropertyModeType.fixed_readonly); 

Work area properties are set to normal mode by default.




Professional IBM WebSphere 5. 0 Applicationa Server
Professional IBM WebSphere 5. 0 Applicationa Server
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 135

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net