BEA Logo BEA WLCS Release Release Number

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   WLCS Doc Home   |   WLCS Components Developer's Guide   |   Previous Topic   |   Next Topic   |   Contents   |   Index

Development Process

 

WebLogic Commerce Server (WLCS) provides prebuilt Enterprise JavaBean (EJB) components that you can use in your e-commerce Web applications. In the Java implementation source code that WLCS generates, you can add your business logic between specially provided code markers. If needed, you can also extend the WLCS components to add new components that match your specific business requirements.

The first section in this chapter outlines the overall development process. Subsequent sections provide details about each step. The following topics are presented:

 


What is the overall development process?

You can create EJB components by modeling them using the Unified Modeling Language(UML) and then generating Java source code. This technique utilizes a UML drawing tool, in this case Rational RoseTM, and creates an intermediate file that describes that model. That file is transformed by a WLCS application called the Smart Generator into the Java classes that make up one or more EJBs.

Code generation from UML has long been recognized as a promising technology. This technique is powerful because it allows the designer to model the components in a natural way without being concerned with implementation-specific details.

Despite its promise, this technique has not been adopted widely for a number of reasons:

The WLCS utilities solve these problems by going a step further. The utilities do not assume a direct mapping from the model to the underlying language constructs. The user models the business objects and the Smart Generator creates a set of classes that implements these objects with reference to the Enterprise JavaBeans 1.1 Specification. Many of the laborious tasks of creating access methods and handling containment of references is automatically handled.

The WLCS Smart Generator also uses intelligent algorithms to generate sensible naming for collections and methods. In addition, it generates documentation for these classes using the same intelligent naming scheme. Because the Smart Generator embeds code markers, it is possible for developers to add the business logic and then resynchronize those changes with the model.

Figure 3-1 introduces the development process when you use WLCS components.

Figure 3-1 WLCS Components Development Process

The overall steps are as follows:

Before you begin: copy the installed WLCS model

Go to the "model\BEA WeblogicCommerce\" directory found under the WLCS installation directory. Create a separate work directory and copy the BEA WeblogicCommerce.mdl model file to your work directory.

Step 1: Export the WLCS model in Rational Rose

Start Rational RoseTM, a graphical UML modeling product. Open your copy of the WLCS Components model, and use the WLCS plug-in to export the model to an intermediate file (*.tast).

Step 2: Run the WLCS Smart Generator

From the Rose menu, or the Windows Start menu, or a command prompt, run the WLCS Smart Generator. The Smart Generator is a Java application that reads the *.tast model definition file and generates the Java source files and EJB Deployment Descriptors.

Step 3: Edit the Java files: Add Your Business Logic

Edit the generated *Impl.java source files to add your business logic between the provided code markers. Because the Smart Generator embeds code markers, it is possible for you to add the business logic and then resynchronize those changes with the model.

Step 4: Run the EJB Compiler

Run the EJB compiler to generate the Java class files for your EJBs.

Step 5: Deploy your application, and start the server

Deploy the application using either Bean-Managed Persistence (BMP) or Conainer-Managed Persistence (CMP) to the host system or systems. Then start the WLCS Server on each machine that hosts the application.

Step 6: If desired, change your copy of the model, and iterate

If you want, you can change your copy of the WLCS model, adding new components or business policies that extend the ones provided by WLCS. You can then iterate through the development process (starting again at step 1). Smart Generator preserves the changes you made to the *Impl.java source files by locating your additions within the code markers.

Subsequent sections in this chapter provide details on the steps in the development process.

 


Before You Begin: Copy the Model

This prerequisite step is simple.

  1. Go to the "model\BEA WeblogicCommerce\" directory found under the WLCS installation directory. The BEA WeblogicCommerce.mdl file in that directory is the model.

  2. Create a subdirectory that will contain your copy of the model. In the WLCS Components Tour, readers are instructed to create a \model\tour\ subdirectory. However, you can create your work directory in a location that is separate from the installed WLCS folder hierarchy, such as d:\myWebApps\work\.

  3. Copy the WLCS Component model file, BEA WeblogicCommerce.mdl, to the work directory that you created.

 


Step 1: Export the WLCS model in Rational Rose

Start Rational RoseTM, a graphical UML modeling product. If you installed the WLCS software after you installed Rational Rose, as described in the WLCS Installation Guide, the WLCS plug-in to Rational Rose is already in place.

Open your copy of the WLCS Components model, and export the model to an intermediate definition file (*.tast). If at this time you are not extending the model and generating new classes based on existing WLCS classes, the procedure in this section is simple.

(See the section Step 6: If desired, change the model, and iterate for more advanced considerations if you are extending the WLCS classes.)

The steps during your initial cycle through the development process are as follows:

  1. Start Rational Rose. From the Windows Start menu, select Start --> Programs --> Rational Rose...

  2. From the Rational Rose top-level menu, click File --> Open, and browse to the directory where you put your copy of the model file, BEA WeblogicCommerce.mdl.

  3. Double click on the BEA WeblogicCommerce.mdl file. Rational Rose opens the model.

  4. From the Rational Rose top-level menu, click Tools --> WeblogicCommerce--> Export Model As...

  5. The WLCS plug-in to Rational Rose displays the following screen:

  6. Enter a file name for the model definition file. The default file type is .tast.

  7. The WLCS plug-in to Rational Rose displays a confirmation message when the export operation completes successfully:

 


Step 2: Run the WLCS Smart Generator

The WLCS Smart Generator reads the *.tast model definition file and generates the Java source files based on an industry standard modeling language.

Advantages

Smart Generator provides the most comprehensive EJB code generation in the industry. The EJB code that is generated by the WLCS Smart Generator is optimized for the high performance demands of interactive e-commerce Web applications. The code is based on input from industry-leading persistence experts and systems integrators. The advantages of using the WLCS Smart Generator include:

After you update the generated Java implementation files, where you add your business logic (Step 3 in the development process), the WLCS Smart Generator reads in your changes the next time it runs, preserves your changes, and reflects the changes back in your copy of the model. Special code markers are provided in the generated *Impl.java files that enable the Smart Generator to synchronize the model with your business logic code.

Define a New Project

To define a new Smart Generator project, follow these steps. You can also see these steps with sample values in the WLCS Components Tour. The tour includes a great walk-through of extending an Item component and extending a pricing business policy.

  1. Start the Smart Generator. Use one of the following options:

  2. On the initial Smart Generator screen, click the New button.

  3. Smart Generator displays its Project Properties screen. For example:

  4. In the Project Name field, enter a descriptive project name.

  5. In the EJB Code Generation Output Directory, enter the location for the generated Java source files. This is the location where Smart Generator will place the Java interfaces, business logic, and other core EJB code.

  6. In the Deploy Code Generation Output Directory, enter the location for the generated deployment code source files. This is the location where Smart Generator will place deployment descriptors and files containing JDBC instructions to persist Entity Beans using a specified database map.

  7. In the TAST Model File field, enter the name of the *.tast file you exported from your copy of the WLCS model (in Step 1).

  8. In the Save Project To field, designate a directory that will contain the project definition file.

  9. Click the OK button.

Configure the Project

  1. Click on the Packages tab.

  2. In the Packages pane, click on the package(s) you want to implement.

  3. In the Classes pane, double-click on the boxes next to the classes you want to implement. Double-clicking adds checkmarks next to selected classes.

  4. Click OK.

  5. Select Configuration--> Options from the Smart Generator menu. The User Options screen is displayed:

  6. If needed, you can enter the following options on this Smart Generator screen:

    -trace 

    Sets the trace switch. The default value is g, which enables a code Generator trace. Other options: -trace c (compiler trace), -trace t (Tast processor trace), and -trace + (trace all).

    -tast

    Sets the metadata exchange format (default and only option in the current release).

    -root

    Sets the location of the root directory for the .java source files to be generated.

    -deployment_root

    Sets the root directory for output of deployment-specific code.

    -classes (c1, c2, c3)

    Allows you to specify a subset of classes to be processed by the next Generate operation in the WLCS Smart Generator. Enclose multiple entries in parentheses, separated by a comma. There is no default.

    -bmp

    Switch to specify that you do not want to use Bean-Managed persistence. In other words, sets bean-managed persistence to off. Do this if you want to use container-managed persistence instead.

    The default is to deploy with this switch on using bean-managed persistence on a relational database such as Oracle. In the default on mode, the Smart Generator references a database mapping properties file to generate the appropriate database-related code.

  7. On the User Options screen, you can also click the Java tab if you want to specify Java compiler options and related options. The WLCS Smart Generator displays a screen similar to the following:

  8. Click the Ok button after you enter any compiler options.

Generate the Java Sources

When you are ready to generate the Java sources, click the Generate button on the main WLCS Smart Generator screen. Wait for the Smart Generator to complete its work. You can click the Output Console tab to view messages recorded during the generation step. Look for the "Compiler done" message at the end of the console output.

For example:

Click the Exit button to close the WLCS Smart Generator.

 


Step 3: Add Your Business Logic: Edit the Java files and Compile Them

  1. Edit the Java files to add your business logic.

    Edit the generated *Impl.java source files to add your business logic between the provided code markers. Because the WLCS Smart Generator embeds code markers, it is possible for you to add the business logic and then resynchronize those changes with the model.

    When you run the Smart Generator again, it recognizes the changes you have made in your *Impl.java sources and reflects those changes in the model.

    The code fragment in Listing 3-1 shows the type of code markers that are provided by the WLCS Smart Generator. The sample generated implementation file is BeanieHatPricePolicy.java, which you can create by running the WLCS Components Technical Tour in the online documentation. A bold typeface is used in the listing to highlight the markers.

    Note: In all cases, the end tag, such as $_End, must appear before the closing brace of the additional method.

    Listing 3-1 Code Markers Indicating Where to Insert Your Business Logic


    package examples.buybeans.tour;

    import theory.smart.foundation.*;
    import theory.smart.util.*;

    //$Import$_Begin ------------ CUSTOM CODE ---------------
    // Place additional import statements here
    //$Import$_End ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

       .
    .
    .

    class BeanieHatPricePolicyImpl implements BeanieHatPricePolicy
    //$Implements$_Begin ------------ CUSTOM CODE ---------------
    // Add interfaces that are implemented here
    //$Implements$_End ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

       .
    .
    .

    //$AdditionalAttributeDeclarations$_Begin ------------ CUSTOM CODE ---------------
    // Add additional attribute declarations here
    //$AdditionalAttributeDeclarations$_End ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

       .
    .
    .

    protected BeanieHatPricePolicyImpl() 
    {
    super();
    //$Constructor$_Begin ------------ CUSTOM CODE ---------------
    // Add constructor code here
    //$Constructor$_End ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    }

       .
    .
    .

    //$MethodException theory.smart.axiom.units.Price calculatePrice(theory.smart.ebusiness.item.Item item, theory.smart.axiom.units.Quantity qty, theory.smart.ebusiness.customer.Customer customer)$_Begin ------------ CUSTOM CODE ---------------

    // Add additional exceptions here

    //$MethodException theory.smart.axiom.units.Price calculatePrice(theory.smart.ebusiness.item.Item item, theory.smart.axiom.units.Quantity qty, theory.smart.ebusiness.customer.Customer customer)$_End   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    {
    //$Method theory.smart.axiom.units.Price calculatePrice(theory.smart.ebusiness.item.Item item, theory.smart.axiom.units.Quantity qty, theory.smart.ebusiness.customer.Customer customer)$_Begin ------------ CUSTOM CODE ---------------

      return null; //in Components Tour, custom pricing policy
    code in WLCS documentation is inserted here...

    //$Method theory.smart.axiom.units.Price calculatePrice(theory.smart.ebusiness.item.Item item, theory.smart.axiom.units.Quantity qty, theory.smart.ebusiness.customer.Customer customer)$_End   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    }

       .
    .
    .


    Note: If you change the signature of a method it will not be properly managed by the WLCS Smart Generator. This happens because the round-trip engineering feature works by matching the exact signature of the method and the parameters. If a generated method is no longer present in the model it will simply be deleted, along with the associated implementation. To avoid this situation, you must make matching changes in the model and the source code. As a consequence it is extremely important to consider the parameters to methods up front so as to avoid this problem.

  2. Compile the *.java source files with any supported Java compiler. For example:

    javac surfcity.java sunhat.java

 


Step 4: Run the EJB Compiler

The EJB compiler (ejbc) generates container classes according to the deployment properties you have specified in your deployment files. For more information on deploying EJBS, see the topics Deploying EJBs in WebLogic Server and Deploying EJBs with DeployerTool in the BEA WebLogic Server Enterprise JavaBeans documentation.

To run the EJB compiler against your files:

  1. Create the files ejb-jar.xml and weblogic-jar.xml according to the Weblogic EJB deployment guide. For container-managed persistence (CMP) deployments, the beanname-CMP-RDBMS.xml will also be needed.

  2. Create a deployment jar file that contains the xml files and the Home, Remote and Impl class files. To do this, use the syntax jar cvf <jar-file> <files...> For example:

    jar cvf morehats.jar propeller.class button.class

    Note: For help, type jar at the command prompt, and it will show the usage parameters.

  3. Run ejbc on the deployment jar. The server and client stubs will be generated inside that jar.

  4. Finally, copy your application JAR files to the deployment system that will host your application.

You can automate running the EJB compiler tasks for subsequent builds by creating a *.bat (NT) or *.sh (Solaris) build script file. For an example of a build script, see the tour-build.bat script in bin\win32 under the WLCS installed directory. In addition to generating the *.class bytecodes for your application, the script should create or update the Java Archive (JAR) file for your application.

Note: tour-build.bat will compile the tour files, tour-deploy.bat will jar them up, and run ejbc on that jar.

 


Step 5: Deploy your application, and start the server

Deploy your application using either Bean-Managed Persistence (BMP) or Conainer-Managed Persistence (CMP) to the server. Then start the WLCS Server on each machine that hosts the application.

This section provides a brief overview of deployment. For more details, see Deploying Your Application.

Before You Start the WebLogic Application Server

Before you start the WebLogic application server, you must do the following:

The WLCS EJB source code is independent of the persistence method, whether it is container-managed or any implementation of bean-managed persistence.

The source code that uses JDBC instructions to persist Entity Beans is generated according to one of the BEA reference implementations of bean-managed persistence. If you use the reference data model, the source code may be used as generated. The more likely case is that the JDBC source code may be used as templates to persist EJBs to a legacy data model.

One of the advantages of the WLCS approach is that business logic and other core EJB source code is independent of the persistence implementation. This isolates business application development from database development and schema changes.

Starting the Server

On the deployment system that will host your application, you must start the WebLogic Server.

  1. Edit the weblogic.properties file so that the jar created in the last step is part of the weblogic.ejb.deploy field.

  2. Make sure that the class path set in sethome.sh or sethome.bat points to the class files that are needed by your bean. Also, make sure that the JAR file that you created is not in the classpath.

  3. Start the server using either StartCommerce.sh for UNIX systems or StartCommerce.bat for Windows NT systems.

 


Step 6: If desired, change the model, and iterate

If desired, you can change your copy of the WLCS model, adding new components or business policies that extend the ones provided by WLCS. You can then iterate through the development process (starting again at step 1).

When you extend the WLCS model, Smart Generator preserves any changes you made to the *Impl.java source files by locating your additions in between the code markers.

Changing your copy of the model requires a basic understanding of:

To master these concepts, we have provided the following topics in this section:

Do I have to be a Rational Rose or UML Expert?

It is not necessary to be an expert in UML concepts or Rational Rose to model your EJBs. The remainder of this chapter takes a step-by-step approach to explain our technique to creating EJBs from UML. This discussion does not assume a familiarity with either of these topics and provides introductory explanations of the key elements of each. While knowledge of these specific technologies is not assumed, familiarity with the underlying concepts of object-oriented design, distributed objects, and transaction services is required.

There are a number of references in this document to various "Design Patterns" and "Analysis Patterns". There is a welcome trend towards documenting these axiomatic solutions to common computer science problems.

Understanding the Foundation Package and Stereotypes

The theory.smart.foundation package is a set of classes from which the WebLogic Commerce Server components are built. These classes provide the building blocks for the value added features of our components. Most of the classes that are generated from the model are derived from classes in the Foundation package.

For example, the theory.smart.ebusiness package contains classes that are built on the Foundation package.

To simplify the complexity of the UML diagrams, the Foundation package relationships are described through class stereotypes rather than inheritance. Each of these stereotypes is used to model certain behaviors and implies the presence of additional methods. This section discusses the Foundation package from a conceptual viewpoint. If you need to extend the functionality of theory.smart.ebusiness classes, it is helpful to first understand the theory.smart.Foundation package.

With that goal in mind, this section describes the following concepts used in the Foundation package:

Belongings

A Belonging is the simplest form of a WLCS Component. A Belonging is a lightweight, local object that can be serialized. A Belonging gets its name because it must "belong" to, or be acquired from, another object, typically a Session or Entity. It must be serializable so that it can be persisted with the class to which it belongs and passed remotely as a parameter.

One of the key characteristics of a Belonging is that it must be implemented using the Abstract Factory pattern. This means that for each belonging there is a home class, an interface, and at least one implementation of that interface. Because access to the object is through an interface, there is a guaranteed level of abstraction. This provides a great deal of flexibility because it means that you can substitute implementations. You could, for instance, make the object remote without changing the code that uses it. Alternatively, you might substitute different business logic at runtime by changing the implementation returned by the home class.

Implementing all these classes by hand is lot of work. The WebLogic Commerce Server development tools simplify the process by generating all of the necessary classes automatically. You can fully concentrate on modeling the attributes and methods so that they fit the needs of your business.

Sessions

Session components, implemented as Session EJBeans, are used to model service-oriented objects. The key concept is that a Session is an object that provides access to a service implemented in itself or somewhere else on the network. Attributes of a session are used only to configure it for use during the lifecycle of that session. It is important to note that the attributes of a Session are not persistent. The business methods are the most important part of a Session.

Sessions provide a way of remotely implementing business logic, thus extending the reach of your client application. For instance, when you need to perform an extended set of operations on a collection of remote objects it often makes sense to create a "Manager". The Manager object can be co-located with the objects it will be operating on. This will reduce the network overhead and latency.

Sessions are also commonly used to provide an interface to a legacy system or to a service that is pinned to a specific piece of hardware. The remote interface allows the client software to access the remote device as if it were local.

Finally, by wrapping a subsystem and factoring out the functions common to similar systems it is possible to provide a level of redundancy. An example of this would be the case where there are multiple providers of credit card validation services. These systems would likely have similar function but different implementations. By creating a common interface to use the different implementations, it is possible to load balance between them or substitute one for the other.

Entity

An Entity, implemented as an Entity EJB, is an object with staying power. Persistence is the key aspect of an Entity object. In its simplest form, an instance of an entity could be the equivalent of a single row in a relational database. This is an over-simplification because each Entity may include collections of attributes and implement business methods.

Entities are representative of the attributes of which they are composed. This is what distinguishes them from Sessions, which represent a collection of services. As a general rule Entities do not implement sophisticated business logic, instead, they are the components that are acted upon.

Configurable Entity

In addition to the standard qualities associated with an EJB Entity, the WLCS Component software provides dynamic configuration. Dynamic configuration is the ability to add properties and methods at runtime and is provided by the Configurable Entity. The Configurable interface allows the programmer to associate a named value with the Entity. These values are persisted separately so that they are permanently associated with the object without affecting the underlying schema.

When the value stored in a Configurable Entity is a method, the result is the ability to exchange the implementation of a method dynamically or a "Pluggable Method" which is the implementation of the "Strategy" pattern.

Business Policy

Configurable Entities can be arranged in a hierarchy of successors. When this type of hierarchy is in place, a request to retrieve a value from a Configurable Entity triggers an upward search through the hierarchy of successors until a matching value is found or the top of the hierarchy is reached. This is the implementation of the "Chain of Responsibility" design pattern.

The combination of "Pluggable Methods" and the hierarchy of succession is called a Business Policy.

Workflow

For many business applications a simple mechanism to maintain internal state is all that is required to achieve a basic level of workflow. The WLCS software provides such a capability for defining and verifying the states and events that describe a business process. What this means to the developer is that they can represent this process as a state diagram and then verify the legitimacy of business method invocations with a single method call to ask for a transition. Adding a step is as simple as adding a new state. The engine will then enforce the rule that this step must be taken without changes to existing code.

Smart Features

The WLCS Components software implements built-in advanced features that considerably improve the ease of use and efficiency of the final system.

SmartKey

The EJB specification requires that for each Entity there is a class that represents the attributes of the primary key of that class. This Primary Key class is used to find and test the equality of instances of Entity objects. To accomplish these simple goals the EJB specification only requires that the Primary Key class must be serializable.

The SmartKey interface extends this functionality and requires the implementation of the Comparable interface from the java collection API. This is so that SmartKeys can be easily compared and stored in ordered lists. The result is that it is easy to model relationships that require the ordering of Entities.

The toString method of a SmartKey simplifies the implementation of profiling and debugging code.

SmartHandle

The EJB specification provides for the passing of lightweight references to Enterprise Java Beans through the use of Handles. A handle in EJB is an opaque type that can be converted to and from an EJB Object. A handle is required to implement a test for equality such that given two handles it is possible to determine if they refer to the same Session or Entity object.

For a WLCS Entity component it is possible to create a SmartHandle that includes the object's associated SmartKey. Because the SmartKey implements the Comparable interface it is possible to order a list of smart handles without accessing the remote objects that they refer to. This simple mechanism greatly improves performance.

SmartValue

Each Entity is composed of the attributes that describe it. In order to encapsulate the remote objects all attributes must be read and written through accessor methods, typically named get<Attr> and set<Attr>. This has the negative consequence that retrieving the attributes of an entity may result in many remote method invocations. To alleviate this problem the WLCS software provides a convenience class, derived from SmartValue, that contains a copy of all the top-level attributes.

Understanding the Basic UML Modeling Notations

You only need to know a small subset of the UML notations to use the WLCS components model. This section explains the UML notations for:

UML describes objects and their relationships graphically. The WLCS Components software uses UML as a mechanism for simplifying the design and implementation of EJBs. Before we discuss the details, let's review some of the UML notation from a higher level perspective. In this section we focus on the aspects of the notation that are of particular interest to the WLCS Smart Generator, analyzing portions of the sample UML diagram in Figure 3-2.

Figure 3-2 Sample UML Diagram

Classes and Stereotypes

Let's start by focusing on the Java classess and stereotypes in Figure 3-3.

Figure 3-3 Compartments in each Class Box

Each of the rectangles in a diagram is a representation of a class in UML. There are generally three compartments in each class box. A compartment may be left out if it is empty or if the details of the contents are not pertinent to a particular diagram. The latter is often the case when an object from another package is referenced.

The upper most box holds the class name and its stereotype. A stereotype is a "sub-classification" of an element in the model. It is represented as the name of the stereotype enclosed in guillemets, as in <<stereotype>>. In UML, anything can be tagged with a stereotype. In the previous diagram, the Item class is stereotyped as a Configurable Entity. This means that it would have the qualities of one as described in the section Entity.

Attributes are listed in the second compartment. In UML the name of the attribute is specified first followed by its type. The name and the type are separated by a colon. It is notable because it is different from the Java language. It works well for object oriented modeling which is generally an iterative process. Often times a designer will list the attributes of class without specifying types the first time through. The same techinique holds true when specifying the arguments to a method. Note that as already mentioned, attributes can be decorated with a stereotype. The stereotype precedes the attribute and is embedded in guillemets as before.

The third and final compartment lists the methods. The return type is listed after the closing parentheses and is separated from the class definition with a colon. Often the display of the parameters and the return value are supressed on the diagram because they consume a great deal of space.

When specifying attributes and methods it is possible in the UML to indicate whether or not they are private, protected, or public. The "tilted brick" icon to the left will have slight variations depending on this.

Inheritance

Figure 3-4 focuses on the UML notation for inheritance.

Figure 3-4 UML Notation for Inheritance

In a UML diagram, inheritance is depicted an unfilled arrow that points from the subclass towards its parent. In this case the ItemPriceCalculationPolicy will have a calculatePrice method through inheritance. The subclass will share all of the properties and attributes of its parent.

Aggregation and Multiplicity

Figure 3-5 illustrates the UML notations for concepts called aggregation and multiplicity.

Figure 3-5 UML Notation for Aggregation and Multiplicity

Aggregation is used to describe a containment relationship between classes. This is an alternative to simply defining an attribute with the type of the class. In UML this means that the contained object shares a life cycle with the containing object. That is, the containing object holds the only reference to it and is responsible for removing the object upon when it, itself, is removed.

Aggregation is depicted in UML with a line that extends from the containing to the contained item. The line begins with an oblong diamond that specifies a category of containment. A hollow diamond is used to show that the object is being contained by reference. A solid diamond specifies that the object is contained by value.

It is also possible to specify a multiplicity for the object being contained. Options are 1 (one to one), 0..1 (optionally null for references), or 0..* (zero to many). As with all other elements of the UML it is possible to stereotype the relationship. It is also possible to name an aggregation, although there is no example of this in the above diagram.

Packages

Figure 3-6 illustrates the UML notation for the relationship between packages.

Figure 3-6 UML Notation for Packages

Packages are used to group classes and other packages in to a hierarchy. Each package will contains classes and/or other packages. When the classes of one package use the classes of another this is depicted as a dotted line with an arrow in the appropriate directions. This same "uses" notation can be applied to classes as well.

WLCS Smart Generator Rules: Factors that Influence the Generated Java Files

This section explains how the WLCS Smart Generator transforms a UML diagram into EJB components. We will describe the Java code that will be generated as the result of making specific notations in a UML diagram.

Classes

Only classes in the model that are stereotyped as eBusiness Smart Component (eBSC) will result in the generation of Java classes. There is not a one-to-one mapping between each class in the UML model and Java. In particular, all eBSCs are implemented using the Abstract Factory pattern. This means that there will be at least one interface and two Java classes generated for each eBSC that is modeled in UML. In addition, each Entity eBSC will have an associated Primary Key and Value class that is generated as well.

The following table describes the mapping of classes based on the class stereotype.

Stereotype

Class Only

Interface

Home

Impl

PK

Value

BSC Belonging


[x]

[x]

[x]



BSC Session


[x]

[x]

[x]



BSC Entity


[x]

[x]

[x]

[x]

[x]

BSC Workflow

[x]






BSC Business Policy

[x]






The naming convention for the generated classes is a follows:

Primary Key and Value

For Entity Components there are two special classes that are generated. The Primary Key class is a Java class with public members for each of the attributes that are stereotyped as <<BSC.PrimaryKey>>. The primary key class is used by the create and findByPrimaryKey methods of the generated home class.

Listing 3-2 demonstrates the usage of the PrimaryKey class.

Listing 3-2 Use of the PrimaryKey Class


public class OrderPk extends SmartKey implements java.io.Serializable
{
public String key;

public OrderPk(
{
super();
}

    more code here

}

public interface OrderHome extends SmartEJBHome
{
public Order create(theory.smart.ebusiness.order.OrderPk orderPk )
throws CreateException, RemoteException;
Order findByPrimaryKey(theory.smart.ebusiness.order.OrderPk orderPk)
throws RemoteException, FinderException;
}

The Value class is a Java class with public members for each of the attributes of the associated Entity. This includes attributes that are specified through aggregation. This class is used by the generated Value accessor methods. The purpose of these method is to simplify the retrieval of multiple attributes and reduce the overhead associated with remote method invocation.

Listing 3-3 shows the use of Value objects in the code generated by the WLCS Smart Generator. Use caution when you use the setByValue method because there is no built-in Entity locking. When using the setByValue on an Entity object it is important to realize that the attributes which are members of the primary key cannot and will not be updated. This is because as part of the identity of the Entity they are immutable.

Listing 3-3 Use of Value Objects


public class ItemValue extends SmartValue
{
public String version;
public String identifier;
public String supplier;
public String description;
public theory.smart.axiom.units.Price price;
public LinkedList qualities;

 protected ItemValue()
{
super();
}
}

public interface Item extends ConfigurableEntity
{
public ItemValue getItemByValue() throws RemoteException;
public void setItemByValue(ItemValue value) throws RemoteException;
//...
}

Interfaces, Homes, and Implementations

The Abstract Factory pattern requires that objects be accessed only through their interfaces and that the classes that implement those interfaces be acquired only through a factory class. The factory class in the case of EJB is referred to as a Home. This has slightly different implications for EJB components and Belongings.

When dealing with Session and Entity objects, run the EJB compiler to create the appropriate proxies stubs and skeletons. At deployment time the application server will be responsible for registering the home interface with the Java Naming and Directory Interface(JNDI) so that users of the EJBs will be able to create and find them.

For Belongings, the home, interface, and implementation will reside wherever they are instantiated. Belongings are always passed by value. When a belonging is used as the parameter to a method of a Session or Entity it will be serialized and then reinstantiated on the server. To make this happen the Java class associated with the belonging must be available in the class path on the server.

The deployment implication is that the release of these classes must be coordinated between the client and the server.

The Home interface is where finder methods reside. A finder method is one that locates one or more preexisting entities. The WLCS Smart Generator will automatically generate a finder method based on the primaryKey, as shown in Listing 3-2.

It is often necessary to create finders that search for entities based on the values of some other attributes. Adding an operation to the main class and stereotyping it as <<BSC.Home.Operation>> will accomplish this. The resulting method will be generated into the associated home class.

Attributes and Accessor Methods

For each attribute that is specified in the WLCS Components model a pair of accessor methods are generated. The get<AttributeName> method will retrieve the value of the attribute from the remote object and return it to the client. The set<AttributeName> method will pass the attribute to the remote object where it will be updated. In the case of an Entity the entire object will be marked as dirty such that the application server will know that the changed values need to be persisted in the database. (The "isDirty" attribute is specific to BEA WebLogic Server.) This is true of Sessions to a lesser degree in that many application servers perform a serialization of Session beans for the purpose of optimizing the caching of Sessions.

The following listing shows the generated accessors.

Listing 3-4 Generated Accessors


public interface Item extends ConfigurableEntity
{
public String getSupplier() throws RemoteException;
public String getIdentifier() throws RemoteException;
public String getVersion() throws RemoteException;

  public String getDescription() throws RemoteException;
public void setDescription(String description) throws RemoteException;
public theory.smart.axiom.units.Price getPrice() throws RemoteException;
public void setPrice(theory.smart.axiom.units.Price price) throws RemoteException;
}

public class ItemImpl extends ConfigurableEntityImpl
{
public String version;
public String identifier;
public String supplier;

  public String description;
public theory.smart.axiom.units.Price price;

 public String getDescription()
{
return (String) description;
}
public void setDescription(String description)
{
isDirty = true;
this.description = (String) description;
}
public String getSupplier()
{
return supplier;
}
public String getIdentifier()
{
return identifier;
}
public String getVersion()
{
return version;
}
public theory.smart.axiom.units.Price getPrice()
{
return (theory.smart.axiom.units.Price) price.value();
}
public void setPrice(theory.smart.axiom.units.Price price)
{
isDirty = true;
this.price = (theory.smart.axiom.units.Price) price.value();
}
}


One omission in the previous sample code is that there are no methods for setting attributes that are stereotyped as part of the PrimaryKey for an entity. This is because those attributes are part of the identity of the object and as such they are immutable, cannot be changed.

Accessors are generated for belongings as well. The call to an accessor of a belonging is a direct call to the implementation object.

All of the attributes must be serializable. This also ensures that they can be persisted.

Rules for Aggregation Notations in the UML Diagram

Aggregation allows for the definition of an attribute of a class by drawing a line between it and another class which will be a included as a member. The following rules describe the allowable notations:

Collections

One of the most challenging issues when designing distributed object systems is implementing one-to-many relationships between objects. When modeling eBSC in UML such relationships are described by stereotyping either an attribute or an aggregation with a multiplicity of zero or more.

When an aggregation relationship is stereotyped as a particular collection type, the internal attribute reflects that choice and the appropriate accessors are generated. The table below describes the options, a brief description of their usage, and the Java 2 SDK class upon which the implementation is based. See the Java 2 SDK documentation at http://java.sun.com/products/jdk/1.2/docs/index.html for more details about the features of each collection type.

Table 3-1 Collection Stereotype Mappings

Stereotype Name

Purpose

Collection Type

BSC.Collection.Set

A collection that contains no duplicates and in which there is no implied ordering.

java.util.Collection.TreeSet

BSC.Collection.Array

An ordered collection that is stored as contiguous elements. This allows for optimal random access so that operations like re-sorting can be executed quickly.

java.util.Collection.ArrayList

BSC.Collection.List

An ordered list that optimizes insertions at the ends.

java.util.Collection.LinkedList

BSC.Collection.Map

A collection that is indexed by string and optimized for quick lookup. Iteration will be in ascending order according to the natural sort method.

java.util.Collection.TreeMap

The accessors for collections are generated for each stereotype as described in Table 3-2. The table uses a shorthand syntax to convey which accessors are generated when a given stereotype is chosen. The token <Attribute> is replaced by the name of the attribute or aggregation as specified in the model. In the case of methods that accept or return a collection, the type is stereotype specific as defined in Table 3-1. The details of the parameters and return values are implied so that the table itself can be concise. While there is no true inheritance relationship, it should be considered that Set serves as a basis for Array, which is a basis for List. Map is different in that it supports lookup by key.

In the case where an aggregation to an entity is specified by value, an additional group of methods is generated. These methods simplify the maintenance of the ownership relationship by ensuring that the underlying Entity is removed from its home in conjunction with the removal of its reference from the list. The converse, add by value, is not supported because it would require that the containing entity be aware of the home of the entity to be added.

The Set provides methods for adding and removing attributes from a collection, it provides a "bag" type collection mechanism. The Array provides random access methods and is optimized for random access by integral position, for this reason it is especially useful when multiple sort orders are required. The List provides random access but is optimized for adding at the ends; this makes it good candidate for use when stacks or queues are needed.

The Map makes it possible to index a collection by a String.

Table 3-2

Accessors

Iterator Methods

Entity by Value

Set

add<Attribute>

add<Attributes>
(<CollectionType>)

contains<Attribute>

is<Attributes>Empty

removeAll<Attributes>

get<Attributes>() :<CollectionType>

create<Attribute>Iterator

hasNext<Attribute>

getNext<Attribute>

remove<Attribute>At

remove<Attribute>ByValue

remove<Attributes>ByValueAt

removeAll<Attribute>ByValue


Array

<All of Set > +

add<Attribute>( int position,)

set<Attribute>( int position, )

get<Attribute>( int position)

get<Attributes>( int from, int to)

remove<Attribute>( int position)

indexOf<Attribute>

lastIndexOf<Attribute>

<All of Set> +

add<Attribute>At

set<Attribute>At

getNext<Attribute>

getPrevious<Attribute>

getNext<Attribute>Index

getPrevious<Attribute>
Index

<All of Set> +

remove<Attribute>ByValue(int)


List

<All of Array> +

addFirst<Attribute>

addLast<Attribute>

getFirst<Attribute>

getLast<Attribute>

removeFirst<Attribute>

removeLast<Attribute>

<All of Array>

<All of Array> +

removeFirst<Attribute>ByValue

removeLast<Attribute>ByValue

Map

put<Attribute>(String key)

put<Attributes>(TreeMap)

get<Attribute>ByKey

get<Attributes>(String)

contains<Attribute>Key

contains<Attribute>Value

remove<Attribute>ByKey

removeAll<Attributes>

create<Attribute>Iterator

hasNext<Attribute>

getNext<Attribute>

remove<Attribute>At


<Accessors are defined using

WithKey instead of ByKey>

put<Attribute>ByValue

remove<Attribute>

ByValueWithKey

removeAll<Attributes>ByValue


Generated Accessors by Stereotype

Design Decisions

Now that we have covered the basics, let's discuss some of the choices that you will need to make during the design process. While it would be nice to allow the modeler to design without consideration for implementation details, the reality is that truly good designs take into account deployment-time issues.

Use of Entities versus Sessions

One of the most common issues when modeling EJB is related to legacy systems. These systems very typically provide an API or message-based protocol to allow external systems to access their functionality. The tendency in such cases is to simply model access to such systems as a Session component where each function in the API is a method of the Session bean. In the case of legacy systems that store complex business data and relationships, this is a mistake. In such cases it is best to model the internal objects as Entities where appropriate. This will provide for a more understandable system definition that takes advantage of the important caching and transaction services features of the EJB specification.

Implementing Business Logic in an Entity

In general, Session beans provide a sensible mechanism for implementing "workflow" related business logic. Workflow in this case is logic that coordinates the usage of any number of Entity beans. This has the performance-improving effect of reducing the network overhead associated with executing extended operations remotely. In the case where an Entity bean needs to perform complex business logic on classes that it references, it is best to implement that logic as a method of the Entity bean. This places the business logic where it belongs, with the data that it is manipulating.

Modeling from a Message Specification

There is a strong trend in the industry to translate message specifications, particularly XML DTDs, directly into business objects. While this may be convenient, it may not result in a clean description of the business objects. This is similar to attempt to model a system based solely on the API. A better approach is to consider a message specification as providing insight into a single users perspective of the system. One approach is to consider the messages as method invocations to one or more underlying business objects. The contents of the message can then be modeled as attributes of various underlying objects.

Changing Method Signatures

If you change the signature of a method it will not be properly managed by the WLCS Smart Generator. This happens because the round trip engineering feature works by matching the exact signature of the method and the parameters. If a generated method is no longer present in the model it will simply be deleted, along with the associated implementation. To avoid this situation, you must make matching changes in the model and the source code. As a consequence it is extremely important to consider the parameters to methods up front so as to avoid this problem.