The Enterprise Application Development Platform for VisualAge® Smalltalk Object Extender Edition For VisualAge® Release 4.5 and 5.0 User Guide

The Enterprise Application Development Platform for
VisualAge® Smalltalk Object Extender Edition
For VisualAge® Release 4.5 and 5.0
User Guide

James R. Wason

Senior Technical Staff Member

IBM Global Services

Sterling Forest, New York

wason@us.ibm.com

September 3, 1999

Filename = EADP45.HTM

(c) Copyright IBM Corporation 1999. All rights reserved.


Table of Contents

1.0 Welcome

  • 1.1 What you need to know about VisualAge®?
  • 1.2 Why use EADP?
  • 1.2.1 EADP and Object Extender
  • 1.2.2 Build it fast, build it to last
  • 2.0 What is EADP?

  • 2.1 Complex Object Support
  • 2.1.1 Primary Complex Objects
  • 2.1.2 Cascaded Complex Object Actions
  • 2.1.3 Quick Views of Normalized Data
  • 2.1.4 Complex Object Support Terms and Concepts
  • 2.1.4.1 The ruler to subobject relationship
  • 2.1.4.2 A database example.
  • 2.1.4.3 Quick Views
  • 2.1.4.4 Complex Object Presentation and Focal Data
  • 2.2 Version Control Support.
  • 2.2.1 Formal rules for version control manipulation.
  • 2.2.2 Enhanced Complex Object Support
  • 2.2.3 Isolation of the version control mechanism
  • 2.2.4 Support for relating version controlled objects.
  • 2.2.5 Support for CUA presentation
  • 2.2.6 Version approval and formalization
  • 2.2.7 Audit trails
  • 2.2.8 Version Selection Rules
  • 2.3 Business Factor Tables
  • 2.4 Derived Fields
  • 2.4.1 Computed fields within a row.
  • 2.4.2 Derived fields for subobjects.
  • 2.5 Business Policy Support
  • 2.5.1 Business Policies
  • 2.5.2 Business Rules
  • 2.5.3 Triggers
  • 2.5.3.1 Simple Triggers
  • 2.5.3.2 Compound Triggers
  • 2.6 Report and batch interface support
  • 2.6.1 Templates
  • 2.6.2 Macros
  • 2.7 Web support
  • 2.8 Prototype support
  • 3.0 Designing your application to use the EADP

    4.0 Setting up a sample complex object

  • 4.1 What you will achieve
  • 4.2 Importing the EADP Applications.
  • 4.3 Loading VAP fixes to allow ODBC to work.
  • 4.4 Setting up the Object Extender Model.
  • 4.5 Setting up a test application.
  • 4.6 Creating the internal parts
  • 4.6.1 Creating the Customers part
  • 4.6.2 Creating the Item Catalog part
  • 4.6.3 Creating the Orders part
  • 4.6.4 Creating the Line Items part
  • 4.6.5 Finishing touches
  • 4.6.5.1 Column default values
  • 4.6.5.2 Column Names
  • 4.6.5.3 Object Names
  • 4.6.5.4 Column data types
  • 4.6.5.5 Column data names
  • 4.6.5.6 Derived fields
  • 4.7 Creating the list parts
  • 4.7.1 Creating the list part for Orders.
  • 4.7.2 Creating the list part for Line Items.
  • 4.7.3 Testing the Orders and Line Items list parts.
  • 4.7.3.1 Testing customizations.
  • 4.7.4 Entry Panels.
  • 4.7.4.1 Creating the entry panel for Orders.
  • 4.7.4.2 Creating the entry panel for Line Items.
  • 4.7.4.3 Customizations on entry panels.
  • 4.7.5 Complex Object Actions.
  • 4.7.5.1 Adding a Line Item for an Order.
  • 4.7.5.2 Copying Orders and Line Items.
  • 4.7.5.3 Deleting Orders and Line Items.
  • 4.8 Adding Quick View Navigation and Prompts.
  • 4.8.1 Creating the list part for Customers.
  • 4.8.2 Creating the entry panel for Customers.
  • 4.8.3 Creating the list part for the Item Catalog.
  • 4.8.4 Creating the entry panel for Line Items.
  • 4.8.5 Quick View Prompts
  • 4.9 Adding a Selection Popup.
  • 4.9.1 Creating the selection panel for Orders.
  • 4.9.2 Testing Selection
  • 4.9.3 Allowing more general selection
  • 4.9.4 Using EADPTextHelper to add a text menu
  • 4.9.4.1 Using EADPTextHelper in your own parts.
  • 5.0 Setting up a version control sample

  • 5.1 What you will achieve.
  • 5.1.1 Setting up the Object Extender Definition.
  • 5.2 Setting up a version control sample application.
  • 5.3 Creating the internal parts
  • 5.3.1 Creating the Application Control Part.
  • 5.3.2 Creating the Affected Item part.
  • 5.3.3 Updating the Version Control Part.
  • 5.3.4 Creating the Item Header part.
  • 5.3.5 Creating the Component part.
  • 5.4 Creating the list parts
  • 5.4.1 Creating the list part for Item Header.
  • 5.4.1.1 Testing version control
  • 5.4.2 Creating the list part for Components.
  • 5.4.3 Testing the Item Header and Component list parts.
  • 5.4.3.1 Testing cross object selection.
  • 5.4.3.2 Testing version control for subobjects
  • 5.4.4 Entry Panels.
  • 5.4.4.1 Creating the entry panel for Item Header.
  • 5.4.4.2 Quick Open of version controlled data.
  • 5.4.4.3 Creating the entry panel for Components.
  • 5.5 Creating, Deleting and Undoing Versions
  • 5.5.1 Creating a New Version.
  • 5.5.2 Using the Undo Function.
  • 5.5.2.1 Undo of Modified Data.
  • 5.5.2.2 Undo of Inserted Data.
  • 5.5.2.3 Undo of Extracted Data.
  • 5.5.3 Deleting a Version.
  • 5.6 Creating a new item.
  • 6.0 Adding Application Logic

  • 6.1 Business Factor Tables
  • 6.2 Setting Triggers
  • 6.2.1 Setting a Simple Trigger
  • 6.2.2 Setting a Simple BFT Trigger
  • 6.2.3 Setting a Simple Derived Trigger
  • 6.2.4 Setting a Compound Trigger
  • 6.3 Adding Business Rules
  • 6.3.1 Adding Business Rule Example
  • 6.3.2 Adding Error Messages
  • 6.4 Adding Business Policies
  • 6.4.1 Adding Business Policies Example
  • 7.0 Generating Reports and Batch Files

  • 7.1 Creating Report Templates
  • 7.1.1 Opening the Template Editor for Reports
  • 7.1.2 The Structure of a Template
  • 7.1.3 Creating a Template to Start a Report
  • 7.1.4 Adding a Template for Order Data
  • 7.1.5 Adding a Template for Line Item Data
  • 7.1.6 Testing the Report
  • 8.0 The EADP Help Facility

  • 8.1 Enabling EADP help for panels.
  • 8.2 Enabling EADP help for messages.
  • 8.3 Adding new help
  • 8.4 Using EADP help
  • 9.0 Packaging a Runtime Image

    10.0 Adding Web Support

  • 10.1 Create a Web application.
  • 10.2 Creating the list form for Orders.
  • 10.3 Creating the list form for Line Items.
  • 10.4 Creating the entry form for Orders.
  • 10.5 Creating the entry form for Line Items.
  • 10.6 Creating the selection list form for Customers.
  • 10.7 Using customized reports
  • 10.7.1 Starting customized reports
  • 10.7.2 Selecting fields to report.
  • 10.7.3 Creating quick view fields
  • 10.7.4 Creating subobject fields
  • 10.7.5 Adding sort columns
  • 10.7.6 Reporting subobjects
  • 10.7.7 Saving the report
  • 10.7.8 Formatting the report
  • 10.7.8.2 Updating from the report results
  • 10.7.8.2 Updating from the report results
  • 10.7.8.3 Tabular and global updates.
  • 10.7.9 Retrieving and modifying the report
  • 10.7.10 Limiting subobject selection.
  • 10.8 Packaging the Web Application.
  • 10.8.1 EADP support for Web packaging.
  • 10.8.2 Customized reports.
  • 10.9 Version controlled Web presentation.
  • 11.0 Using EADP Interface Support.

  • 11.1 Defining Interface Templates.
  • 11.1.1 Mapping templates to records.
  • 11.1.2 Setting up a template to parse a record.
  • 11.1.3 An interface example.
  • 11.2 Running interfaces.

  • 1.0 Welcome

    Welcome to the Enterprise Application Development Platform (EADP). This guide will explain how the EADP can help you develop VisualAge® applications more effectively. We will begin with a quick overview that describes some of the services that are available, and how you can use the EADP effectively to design and implement your application. Then we will give some detailed examples which should get you ready to build applications on your own using the EADP.


    1.1 What you need to know about VisualAge®?

    The version of EADP described here is an extension of the Object Extender and Web Connection features of VisualAge® for Smalltalk. It provides enhanced support to create sophisticated business applications using visual programming

    Before reading about EADP or attempting the examples, you should be familiar with some of the examples in the Object Extender and Web Connection user guides. You will find that EADP makes the programming involved considerably simpler. However, you should understand how to create models and schemas within Object Extender, and how to configure your system to make use of the Web Connection parts.

    Sample databases are included in this package which allow you to use either DB/2 or an ODBC database as the sample database. If all else fails you should be able to use the dBase 5 driver included as a part of the ODBC package (if you are using AIX and can't get dBase 5 to work, contact me and I will ship you fixes I have made on my own system). Most features will work using the image persistence feature of Object Extender; however, if you do this you will not be able to use the prebuilt sample databases.

    If you want to use the Web page support features of EADP, you must first install the Web Connection feature. You should familiarize yourself with the material in the Web Connection user manual concerning setup of the CGI link. You may want to do some of the easier exercises in the manual to make sure that you have the Web Connection operating properly.

    If you are not familiar with visual programming, don't be discouraged by the amount of drag and drop you need to do in the base VisualAge® product. As you will see, the EADP tool eliminates most of this. EADP visual and web parts have almost all of their connections prepackaged.


    1.2 Why use EADP?

    EADP is the next generation in visual programming. It lets you design complicated business applications using visual design techniques. Using EADP, you can do rapid prototyping and iterative development on applications that were too large for other tools to handle. This greatly increases the chances that your application development will succeed.

    EADP is integrated with the database design environment provided by Object Extender, and adds additional models to control presentation and business logic. The combination provides a total development environment that allows the entire application to be model driven for both design and execution.

    EADP is the fastest, easiest, and sturdiest way to created Web based applications to present and control relational databases. It complements the Web Connection feature of VisualAge® to provide a complete development environment for Web applications.

    The EADP is based on many years of experience in developing large scale data base applications. It pulls out function that has traditionally been considered application specific, and lets you add it to your new application using the same visual programming techniques as the rest of the VisualAge® product. Some examples are:

    1. Centralization of design and implementation. EADP provides a consistent context for all the features you need to produce a complete working application. In EADP, a design element is defined one time in one place, and is consistently applied throughout the application (examples of this are database verifications, external names, version control, and complex object rules). Each of these design elements is isolated and can be changed independently. The EADP toolset gives an organized presentation of these design elements so that you can quickly create them, and continue to control them once they have been created.

    2. Linking together data in different tables. For example, if customer number is part of the purchase order table, providing customer name and address with the list of purchase orders.

    3. Providing transitions from one table to another, for example from a list of purchase orders to the list of lines for a selected purchase order.

    4. Adding derived fields to a list. For example, if the purchase order line includes unit price and quantity. including the total price of the line item (unit cost times quantity) as a derived field.

    5. Adding derived fields based on calculations over a related table. For example, the total cost of a purchase order, which is calculated as the sum of the total price of the lines for that purchase order.

    6. Adding business meanings for the data. The EADP provides two support mechanisms, Business Factor Tables and triggers to do this. These allow you to define date states that are used to drive decisions within the application.

    7. Organizing and isolating business policies and rules. Verifications can be isolated from the rest of the application. Many verifications can be defined completely using visual programming techniques.

    8. Isolating informal data. EADP version control gives you the capability to define persistent units of work, and to keep an audit trail of changes to your data over time.

    9. Generating reports and batch interface files. EADP template processing allows you to quickly define report and batch file layouts.

    10. Enhanced National Language Support. EADP expands the national language support in VisualAge® to include titles for list columns and entry fields, the names of your tables when displayed to the user, and the displayed value for data elements with discrete values.

    1.2.1 EADP and Object Extender

    The Object Extender edition of EADP uses Object Extender facilities for database modeling. This includes defining the relationships that are important for EADP (these are the "quick view" and "ruler to subobject" relationships). EADP function interacts with Object Extender at the model level, so that EADP doesn't care how that model is implemented. For example, you can use Object Extender image persistence instead of the the supplied sample databases to do the samples (of course, you will have to load in the data by hand).

    The application layer of EADP includes logic to handle Object Extender transaction levels. The "quick view" facilities provide an easy way to implement normalized data using Object Extender associations. EADP complex object support works within the context of Object Extender one to many relationships. Finally, EADP version control provides a way of mapping "fuzzy" relationships within Object Extender, and it provides complete application support to make this easy to use within applications.

    EADP visual support enhances the limited Object Extender quick form and quick html facilities, restoring the full function that was available with the earlier database facilities in VisualAge®.

    1.2.2 Build it fast, build it to last

    EADP lets you build a working prototype with complex panel or Web transitions quickly and effectively. More important, it gives you a framework to build an application that is easy to understand and maintain. It does this by allowing you to centralize and control data definitions, NLS support and implementation of business policies. All of these are effectively isolated so that they can be changed without breaking the rest of the application. One final benefit is that EADP provides a well defined context in which to design your application, so the process of translating requirements into implementation becomes greatly simplified.


    2.0 What is EADP?

    EADP provides run-time services which your application can invoke instead of reinventing them. It also provides build time services to allow you to build your application visually using the Composition Editor. These services work together in an integrated manner; however, for convenience, we have broken them out into several components.


    2.1 Complex Object Support

    Some very simple data base applications use only one type of data base table to store their data. Usually, however, several different types of tables are required. The application then needs to present the data from these multiple tables in a way that allows the user to navigate easily through the data.

    2.1.1 Primary Complex Objects

    The ORDERENT database that was shipped as a sample with VisualAge® Version 2 is a fairly typical example. It has four tables: CUSTOMERS, ORDERS, LINE_ITEMS, and ITEM_CATALOG. The LINE_ITEMS table has line items for the purchase order (this is an example of a one-to-many type data relationship that forces use of a separate table). Although it is possible to present all the line items for all the orders in one big list, it makes more sense to select an order first (from a list of selected rows in the ORDERS table), and then use this to select a list of lines for that order. The purchase order, which is the collection of the data in ORDERS and LINE_ITEMS table (for a particular order number) is a small example of a "primary" complex object relationship.

    2.1.2 Cascaded Complex Object Actions

    Once you have set up a primary complex object, the delete and copy actions can cascade through the complex object structure. The same mechanisms that are used to select subobjects for presentation are used to select the subobjects to process for the cascaded actions.

    2.1.3 Quick Views of Normalized Data

    More subtle relationships are to be found among the other tables. For example, the ORDERS table includes CUSTOMER number. However, a user view of the purchase order might want to show additional columns from the CUSTOMERS table, such as name and address information. The "quick view" facility of EADP allows you to include this normalized data using visual programming techniques.

    2.1.4 Complex Object Support Terms and Concepts

    Most applications need to deal with panel transitions and normalized data, but until now the logic to do it has been regarded as application specific. EADP abstracts several behaviors which are common to all complex objects. In order to talk about this, we need to introduce a few new terms and concepts:

    2.1.4.1 The ruler to subobject relationship

    A ruler to subobject relationship is a special kind of one to many relationship where the "one" object controls the "many" object (for example, a purchase order header controls the line items for the purchase order). This is the relationship that glues together complex objects. When an object processes, it does so in the context of its rulers. Within Object Extender, each type of class needs to have a primary key. For a ruler to subject relationship to be in place, the primary key of the ruler must form part of the primary key of the subobject. When this is modeled in Object Extender, the "ruler" relationship becomes one of components of the subobject key. In more complicated applications this can extend to an entire hierarchy (the same table may be both a ruler and a subobject).

    2.1.4.2 A database example.

    The ORDER_NUMBER column (in both ORDERS and LINE_ITEMS) is a good example of a key column. The value in the key column is used to glue together the complex object relationship between the two tables.

    From a database perspective the logical key is a set of key columns which uniquely identifies a particular occurrence of an object. Within a "primary" complex object, the columns of a ruler provide a partial primary key of its associated subobject. For example, the physical key of the Purchase Order Header is ORDER_NUMBER, and the physical Key of the Purchase Order Line is ORDER_NUMBER/ORDER_LINE_NUMBER.

    When this is modeled and mapped within Object Extender it may be a little less obvious. Suppose that onumb is mapped to the ORDER_NUMBER column of the ORDERS table. Originally onumb is mapped to ORDER_NUMBER and lnumb to ORDER_LINE_NUMBER in the LINE_ITEM table. However, when a ruler -> subobject association is set up, the "ruler" relationship in the Lines model takes the place of onumb. So the primary key is now ruler/lnumb (the example for the ORDERENT database will do this in detail).

    EADP function uses a naming convention to pick out which Object Extender relationships are ruler to subobject. The name of the "ruler" role should always be ruler. A subobject can only have one ruler, so this safe.(In addition, as noted above, ruler should form part of the primary key of the subobject). A ruler can have many subobjects; for each, the role name should begin with subobject.

    2.1.4.3 Quick Views

    A quick view is another type of one to many relationship that handles normalized data needed for lookup. For example, references to a customer object from within an orders object. The "one" side of the relationship (the customer) is not the ruler of the order. However, the data for the customer needs to be accessible from within the order.

    Physically, quick views are implemented by mapping the relationship to the primary key column in the source table (the Customer), and to a foreign key (the quick view column) in the target table (the Order). This mapping is done within Object Extender. EADP then allows you to pull in data from the customer (such as name, street, etc.) and include it with the visual presentation and application logic of the Order. To distinguish quick view relationships, the source role should begin with qv.

    2.1.4.4 Complex Object Presentation and Focal Data

    You can visually create the subobject list panel. It is automatically connected to the list panel for its ruler. On the subobject panel you can visually add "focal data" (this is data about the ruler). This is automatically filled in from the selected row for the ruler as the subobject panel is opened. EADP allows you to use the "tear off" and "quick form" capabilities of the Composition Editor to set up the focal data.


    2.2 Version Control Support.

    Most applications need version control. Quite often the initial descriptions of an application may not specifically point this out. However, there are several common application requirements which can be satisfied within the context of the version control support provided here. These are:

    1. The need to segregate work in progress from completed and approved data.

      This requirement is often expressed as the need for a "private cache" for a particular user. The version control support provided by EADP can isolate informal versions (work in progress), from formalized versions.

    2. The need to keep a historical record of data.

      The version control support in EADP keeps back levels of data. It does so selectively (only the data that is actually modified is copied to retain the previous information).

    If you already have specific requirements for version control, you should be able to fit them into the version control mechanisms that EADP provides. EADP version control support isolates properties common to any version control mechanism, and provides a convenient way to plug in the application specific logic. One advantage of this approach is that as your version control requirements evolve, it is likely that you can isolate the changes without affecting the rest of the application. If you originally developed your application without version control, you can add it in later with a minimal amount of effort (as long as the application was developed using EADP).

    EADP provides a default version control mechanism which will be useful for many applications. Named versions are controlled by version selection objects (VSOs). Each version selection object contains the name of the version, and the logical key of data that is version controlled (typically the top level of a complex object). A named version acts as a persistent unit of work; formalizing it is like a unit of work commit. Up to the point of formalization, all the updates done by that version can be rolled back (using the undo function).

    EADP Version Control Support consists of:

    2.2.1 Formal rules for version control manipulation.

    In order to provide generic support for version control, certain formal behaviors must be isolated and abstracted. These are the concepts of logical key (which identifies associated data "up to" version selection), and selection sequence number. The data base columns which are part of the logical key are identified as within Object Extender as a "root" class for table. The primary key for the table class adds sequence number control which allows for multiple versions. There are two sequence numbers include as attributes; an insert sequence number which is part of the primary key, and an extract sequence number which is used along with the insert sequence number to control version selection. A specialized relationship (root to version) is used within Object Extender to associate the root to its versions (when this is modeled, the primary key of the versioned table becomes the root relationship plus the insert sequence number). EADP functions uses Object Extender generated queries to find the root and all its versions, and then uses its own application function to select a version associated to that root class (EADP processes this entirely at the model level, so that version control can be implemented using Object Extender image persistence).

    2.2.2 Enhanced Complex Object Support

    EADP Version Control Support is compatible with Complex Object Support. The ruler -> subobject relationships are mapped root to root if the classes have a root -> version relationship. In addition, there are several new complex object actions (promote, promote verify, and undo), which are cascaded.

    2.2.3 Isolation of the version control mechanism

    The version controlled object understands versions only in terms of the insert and extract sequence. The interpretation of these must be application specific. However, EADP gives you a set of methods to get you started. It also provides support for a common type of version control mechanism (version selection objects) so that you can get this up and running just by setting up the data base tables and Object Extender model.

    2.2.4 Support for relating version controlled objects.

    One of the problems with version control is that relationships get "fuzzy". An initial entity model may show that "A" is related to "B". However, once we introduce version control, "A" may have versions, "B" may have versions, and the relationship itself (if there is intersection data) may have versions also. Now, which version of "A" is related to which version of "B", and with what intersection data? There are some standard rules for sorting this out, and they are provided as a part of EADP.

    These rules are used for selecting objects for quick view and derived (subobject) fields, so that the version control mechanism is fully integrated with the extended features of complex object support.

    2.2.5 Support for CUA presentation

    The CUA presentation of version controlled objects is an extension of the CUA support provided for complex objects. This provides support for updates of version controlled objects (to ensure that an appropriate version is available for update when a version controlled object is opened from an entry or list panel). Presenting the top layer of a version controlled application is particularly tricky, since you need to be able to show all the versions of the top level level objects in the complex object hierarchy. EADP provides mechanisms to provide transitions (using visual programming in the Composition Editor) from a top level list (all versions of several master objects) to a subobject list of data related to one master object at one version.

    2.2.6 Version approval and formalization

    A version of data can be informal (it can be updated but not trusted because it may change) or formal (it can be trusted because it has been approved, but it can no longer be updated). EADP Version Control Support provides mechanisms for segregating formal versions from informal versions, for blocking updates when the version has been formalized, and for progressing a version from informal to formal status, or removing an informal version if it is not approved.

    2.2.7 Audit trails

    Insert/extract control is used to handle multiple versions of data for a complex object. This allows the complex object to be presented or updated at the various versions, without requiring that all the data for the complex object be copied to each version. All the back version can be accessed to provide an audit trail of how the data change over time.

    2.2.8 Version Selection Rules

    EADP uses Object Extender function to find all versions related to a root, and then selects the proper version or versions based on the following rules (in most cases a selection sequence is passed).

    1. Applicable

      This selects the version with insert sequence less than or equal to the selection sequence and extract greater.

    2. Affected At

      This is like the Applicable, but it also includes data that was extracted by the version.

    3. All Versions

      This finds all rows which match the logical key.

    4. VSO Selection

      The version selection object is associated to the root of the top object by a "reverse" ruler -> subobject relationship (the VSO plays the role of ruler, but its primary key includes subobject as a component). In this one case, the ruler is on the "many" side of the one to many relationship.


    2.3 Business Factor Tables

    A business factor table is a mechanism to isolate application decisions from the specific values of data elements. The value of the data element is used as the key to a row of the table. Application decisions are based on values in the corresponding columns. Business factor table support is fully integrated with other EADP functions. A new data type (coded data element) has been introduced for data elements with discrete value. Customization of coded data elements allows you to attach them to business factor tables, and to edit the business factor tables to adjust the row and column values. The business meaning of the particular column (or column value) can be captured in a trigger (see 2.5.3, "Triggers"). BFT's provide enhanced NLS support to display the value of the data element.


    2.4 Derived Fields

    Much of the information that is of interest in an application is not stored directly on the database; instead it has to be derived or computed from the raw data. Business factor tables give one example of how EADP allows you to interpret data into user terms, and to store the business meaning of that data. Derived field support gives you the additional ability to present and manipulate derived data as if it were stored with the rest of the row on the data base. These derived fields can then be used to drive application logic.

    2.4.1 Computed fields within a row.

    EADP allows you to specify formulas to compute fields from data within one row. The fields that can be used in the calculation include other computed fields. For example, the line item includes a column for unit price and a column for quantity. A computed field can be added to multiply these, giving the total cost of the line item.

    2.4.2 Derived fields for subobjects.

    EADP also allows derived fields to be calculated for all rows of a subobject for a particular row (for example, all line items for an order). This can be used to give the total cost of the order as a computed field. The formulas that are supported are sum, first, last, average, minimum, maximum and count. Any of these can be restricted to rows matching selection criteria specified by a trigger (see 2.5.3, "Triggers").


    2.5 Business Policy Support

    Business policy support allows you to control the implementation of business rules within your application. It encourages the isolation of these rules from each other and from the rest of the application, and it provides an efficient and convenient mechanism to implement these rules.

    2.5.1 Business Policies

    Business policies can be defined and described, and rules attached to policies. Policy definition is mainly for documentation purposes. However, attaching rules to policies provides a convenient way to find a particular rule.

    2.5.2 Business Rules

    A business rule is an executable part of the application. Each rule is defined by the following:

    1. The Object Extender class (database table) it acts upon.

    2. The VisualAge® class that implements the rule.

    3. The event that causes the rule to be invoked. These are:

      1. Data creation

      2. Data modification

      3. Any data update (create or modify)

      4. Data deletion

      5. Data formalization

    4. The error message to be issued if the rule fails

    5. Any triggers to be used to check if the rule should be invoked

    When a rule is created, the implementing method for the rule is automatically generated. If the rule is completely defined by its message and triggers, you don't need to do anything else. However, if you need to do more you can change the generated method to add any extra logic that is needed to fully implement the rule. This approach encourages the isolation of the rules logic from the rest of your application, and in many cases it will allow you to implement rules entirely through visual programming.

    2.5.3 Triggers

    A trigger is an evaluation of whether or not the application data meets a certain condition or set of conditions. EADP allows you to define and document triggers, and to use them to drive business logic. It also provides a caching mechanism to allow for the efficient processing of triggers during runtime.

    2.5.3.1 Simple Triggers

    A simple trigger checks the value of a single attribute in a single table Object Extender class (if the attribute is supported by a BFT, it will check the value of a BFT column for the row that matches the value in the database column). EADP provides an external interface to define simple triggers. This includes documentation of what the trigger means. Simple triggers can use quick views and derived fields to make decisions based on complex business information.

    When a simple trigger is evaluated during processing of a business rule, the first check is against the table for the current class. If that table does not match the trigger table, the ruler list is checked. If any ruler is the right table, the trigger is evaluated against it. Finally, subobjects for the current row are checked. If any subobject class matches the table for the trigger, then all rows of the subobject table which match the key of the current row are checked. The trigger is considered true if any of these rows meets the trigger conditions. Trigger results are cached, and the cache is checked first to avoid redundant processing.

    2.5.3.2 Compound Triggers

    A compound trigger is made up of simple or compound triggers. As each trigger is added, it can be evaluated as either true or false to provide the compound result. The set of triggers is then evaluated using "and" (all satisfy the true/false condition for the individual trigger) or "or" (at least one of the triggers satisfies its condition). When a compound trigger is evaluated, the evaluation stops as soon as the compound result has been determined.


    2.6 Report and batch interface support

    EADP uses a system of macros and templates to generate its specialized database queries. The same support can also be used to generate reports and batch interface files. A special macro is provided which allows you to conveniently write reports that include an entire complex object structure.

    This same facility can be used in reverse to parse incoming batch files and use them to update databases controlled by EADP applications. In this case the template is a mask that shows how to parse the incoming records and map the data to fields in internal classes defined to EADP.

    2.6.1 Templates

    A template is a fragment of text with substitutions. The substitution areas are delimited by dollar signs. For report generation, you can:

    1. Put an attribute name as a substitution name. This will place the value of that attribute (for the current row) in the text at that point. The external value (including NLS translations) will be used. You can add formatting information such as alignment after the name of the attribute. The attribute can be an actual data base column, a quick view column, or a derived or computed field.

    2. Indicate that you want to include data for a subobject at this point in the report. The substitution includes the name of the macro to process the subobject (which usually is the standard one provided by EADP), the name of the subobject's internal class, and the name of the template to be used to process the subobject.

    For incoming batch processing, the macro name is the name of a macro that derives data from the input record and maps it to a particular field controlled by an EADP internal class (see 11.0, "Using EADP Interface Support.").

    2.6.2 Macros

    Macros are special VisualAge® classes which are used within template processing to gather data or to decide what to do next. A standard report macro is provided that finds all the subobjects (for the passed subobject type) that match the key of the current row. It then processes the passed template against the subobject row. This macro can be successively invoked by a series of templates to report an entire complex object structure.


    2.7 Web support

    EADP takes advantage of the VisualAge® Web Connection feature. The same complex object presentation that is provided interactively can also be presented as Web pages. Because EADP introduces a controller layer, you can use exactly the same application logic for both interactive and Web presentation.

    EADP also provides a facility to customize Web pages at runtime. This gives a customized report facility for Web users. These customized pages also support tabular update and mass update.


    2.8 Prototype support

    EADP is designed to support rapid prototyping and iterative development. All EADP features (except for selective query of top objects) will work with Object Extender image persistence, so you can develop a prototype at the pure model level, and choose a database implementation later. EADP and Object Extender let you design the database and application in one integrated process.


    3.0 Designing your application to use the EADP

    The function provided in the EADP is an extension of the data base support provided by VisualAge® Object Extender. One important aspect of this is where "persistent" data is defined. Object Extender provides code generation facilities to create the model and service class needed for persistence support. EADP takes full advantage of this. The implication is that you should set up your Object Extender model and generate out the persistent services first. The model definitions for complex object support and version control need to be defined with Object Extender (using the correct naming conventions).

    EADP also influences the way you set up your data base design. It is important to work out the transitions from table to table (this is what turns into the definition of the complex object structures). Once you have established this, make sure that the "key" columns are consistent where ruler -> subobject and root -> version relationships need to be mapped.

    Once you have done this, you should be able to rapidly put up a shell of your application (using visual programming support provided by EADP) that will allow you to select and update the various tables in your application, and navigate through that data.

    EADP also provides a well defined mechanism for implementing business rules. To take full advantage of this, you should be able to relate data conditions to business decisions. This will allow you to set up the necessary business factor tables and triggers. The triggers should become a vocabulary to describe your application in business terms. As you build rules, you should reuse the same vocabulary as much as possible.

    EADP encourages you to make each business rule small and isolated. Business policies can be used to organize these rules. If you are using a top down approach, you can define the policies first, then the rules. However, it is probably better to define the triggers "bottom up" because typically the same trigger will be used in many different rules. If you don't understand the application well enough to do this in the beginning, keep in mind as you implement new rules that you should try to use existing triggers.


    4.0 Setting up a sample complex object

    The first example uses the sample data base ORDERENT which was shipped with the VisualAge® product in Version 2. To install this database

    1. If you are using DB2

      1. You must create the database definition in DB2, and set up a connection for the database. To set up the connection, create the application you will use and set up a connection spec there. After you have created the connection, make sure that you connect it so that it shows up in the list of active connections that is displayed in the next step.

      2. From the System Transcript or a Workspace, issue the following command:
        EADPDatabaseSamples installOrderentSampleData.
        

        When prompted for a connection, use the one you just set up.

    2. EADP also provides sample databases in dBase 5 format. This is a widely used text database, and prior to Relase 5, an ODBC driver was provided as a part of the VisualAge® product. If you have previous versions installed, save the ODBC drivers to use for this example. If you are using dBase 5, you must reinstall EADPR45Fixes as explained in 4.3, "Loading VAP fixes to allow ODBC to work.".

    3. If you are using dBase 5 from the System Transcript or a Workspace, issue the following command:
      EADPOdbcOrderEntrySamples installDatabase
      

      Before installing the database, you must set up ORDERENT as a dBase data source using the ODBC administrator.

    Make sure you have this data base installed, and that you have the data base manager opened before you try the examples.

    The database does not use table qualifiers or primary keys. In order to process it you need to install the Object Extender fixes that are included as part of the EADP package.


    4.1 What you will achieve

    When you have completed this exercise, you will have a complete application allowing you to navigate through the ORDERENT tables. The transitions that you will be able to do are:

    1. From a list of all orders to an entry panel for a particular order. The order list will include quick view data for the customer (name and address information).

    2. From the list or entry panel for an order, to the entry panel for the customer using quick view.

    3. From the list or entry panel for an order, to the list panel for all customers using prompt.

    4. From a list of all orders to a list of line items a particular order. The focal data will be for that particular order, and will include the quick view data for the customer.

    5. From a line item, to the entry panel for the item catalog for the item.

    6. From a line item, to a list of all the entries in the item catalog, using prompt.

    4.2 Importing the EADP Applications.

    The files required for EADP are available via the VisualAge® Object Connection program, Alphaworks and Totally Objects. For Release 4.5 use eadp45.dat, and for Release 5.0 use eadp50.dat as the source libraries.

    Before importing EADP base applications, copy the mpr files eadpea45.mpr and eadpee45.mpr (eadpea50.mpr and eadpee50.mpr for Release 5 )to your VisualAge® mpr directory. You must also copy ewebae45.mpr (ewebae50.mpr) if you are using the web applications. Make sure that you have loaded the database features you are using, and the Web Connection feature if you are using the Web parts. You must also load the Notebook Style Settings View feature (and the fix included in the EADP package). to NLS. The Release 4 code is packaged for import in the

    There are three configuration maps, EADPBase, EADPWeb and EADPPack. To import these, select Tools -> Configuration Maps -> Names, then select the right map and select Import. You will be prompted for the file name where the library is located. You must then load the EADP applications that have been imported (and the special EADP version of VAPTransactions). The easiest way to do this is to stay in Configuration Maps and select the applications to load from there.

    EADPBase has the parts needed to create an interactive application. EADPWeb adds Web Connection support; to use it you need the Web Connection feature to be loaded. For Release 5 this is now included as a part of the base product. EADPPack has the methods needed to package a runtime image.


    4.3 Loading VAP fixes to allow ODBC to work.

    The application EADPR45Fixes has corrections to several VAP methods; unfortunately the redefined methods will be deleted as collisions. These fixes must be loaded to allow the ODBC samples to work (they compensate for the fact that in dBase you cannot provide table prefixes or specify primary keys). To load the fixes, attempt to reload EADPR45Fixes to see which methods collided, then move the colliding methods to the EADPR45Fixes application. Then reload the released version of the application (this time the load will take).


    4.4 Setting up the Object Extender Model.

    You can begin the Object Extender model by importing the schema from the database (orderent) and then generating a model from the schema (user Orderent for the schema and model name). Once you have done this, the following model relationships need to be set up:

    1. A ruler to subobject relationship from Orders to Lines. The role of Orders should be ruler, and the role of Lines is subobject. Note that the "ruler" association replaces the order number attribute in Lines.

    2. A quick view relationship from Customers to Orders. The role of Customer should be qvsource, and the role of Orders is qvtarget. Note that the "qvsource" association replaces the customer number attribute in Orders.

    3. A quick view relationship from Lines to Catalog. The role of Catalog should be qvsource, and the role of Lines is qvtarget. Note that the "qvsource" association replaces the item number attribute in Lines.

    Make sure that primary keys are set up as follows:

    1. Orders

      order number

    2. Lines.

      ruler, line number

    3. Customer

      customer number

    4. Item Catalog

    5. item number

    You must now regenerate the schema to reflect these changes. Make sure that foreign key relationships have been properly identified. You will need to map the associations to the appropriate database columns. You can then generate the Object Extender model and service classes.


    4.5 Setting up a test application.

    1. In the VisualAge® Organizer, create a new application (call it TestOrderEntryEADP). Change the prerequisites to EADPBusinessFactorTables, and the services application generated by Object Extender.

    4.6 Creating the internal parts

    The next step is to create the internal parts to manage the tables and transitions. We'll start with a very small complex object structure; from a list of orders to a list of line items for that order. However, we will also add quick views to the customer and the item catalog.

    Before we can create a quick view to a table, we have to set up the EADP internal class for that table. So we will set up the parts for customers and item catalog first. Then we will set up the top of the complex object (orders) and the subobject (line items).

    4.6.1 Creating the Customers part

    The first step is to establish Customers as a top level object so that it can be linked to Orders using quick view.

    1. In the Organizer, select TestOrderEntryApp as the application (you have to do this because the application hasn't been linked to the EADP parts yet).

    2. From the Organizer menu, select options, then EADP Quick Create.

    3. In the EADP Quick Create window, select ORDERENT as the database. Since this is the first internal part for the application, you will have to specify the application (TestOrderEntryApp), and a Prefix (Test).

    4. Select CUSTOMERS as the table. The Internal class name should default to TestCustomersInternal.

    5. The New button under Internal Class should now be enabled. Press it.

    6. You will be placed in the Composition Editor for TestCustomersInternal. There is one icon showing, for the EADPDatabasePart.

    7. Open settings on the EADPDatabasePart.

    8. Everything has been preset, so you only need to press the Okay button. Note that you need to do this so that the settings that were packaged as the part was created get properly saved.

    9. When you return to the Composition Editor, save the part. Again, this needs to be done even though you didn't change anything to preserve the settings that were set up by Quick Create.

    10. Open database settings again and press cancel (this refreshes the base model with the new values).

    11. Now exit the part.

    4.6.2 Creating the Item Catalog part

    The next step is to establish Item Catalog as a top level object so that it can be linked to Line Items using quick view.

    1. From the Organizer menu, select options, then EADP Quick Create.

    2. In the EADP Quick Create window, select ORDERENT as the database.

    3. Select ITEM_CATALOG as the table. The Internal class name should default to TestItemcatalogInternal.

    4. You will be placed in the Composition Editor for TestItemcatalogInternal. There is one icon showing, for the EADPDatabasePart.

    5. Open settings on the EADPDatabasePart.

    6. Everything has been preset, so you only need to press the Okay button. Note that you need to do this so that the settings that were packaged as the part was created get properly saved.

    7. When you return to the Composition Editor, save the part. Again, this needs to be done even though you didn't change anything to preserve the settings that were set up by Quick Create.

    8. Open database settings again and press cancel (this refreshes the base model with the new values).

    9. Now exit the part.

    4.6.3 Creating the Orders part

    The next step is to establish Orders as the top level object in the complex object structure ORDERS -> LINE_ITEMS.

    1. From the Organizer menu, select options, then EADP Quick Create.

    2. In the EADP Quick Create window, select ORDERENT as the database.

    3. Select ORDERS as the table. The Internal class name should default to TestOrdersInternal.

    4. The New button under Internal Class should now be enabled. Press it.

    5. You will be placed in the Composition Editor for TestOrdersInternal. There is one icon showing, for the EADPDatabasePart.

    6. Open settings on the EADPDatabasePart.

      1. From the drop-down for COLUMNS select qvsource (this is the customer number). Once you select a column, the "Quick View" button should be enabled. Press it, and you will placed in the "Create Quick View" panel.

        1. You should see the columns for the customer table appear in the "Table Columns" list.

        2. Select NAME from the "Table Columns" list. The "Add" button should now be enabled. Press it, and NAME will be added to the "Quick View Columns" list.

        3. Repeat this for any other columns you want to pull into the quick view. In particular, you probably want to add the customer number as a quick view, since it will not show up on the order otherwise.

        4. The "Okay" button should now be enabled. Press it to save your selections and exit the "Create Quick View" panel.

      2. You should now be back to the "EADP Database Part Setting" panel. The "OK" button should now be enabled. Press it.

    7. When you return to the Composition Editor, save the part, reopen the database settings to reset the base model, and exit.

    4.6.4 Creating the Line Items part

    Now that a top level object has been set up for Orders, you can add Line Items as a subobject.

    1. From the Organizer menu, select options, then EADP Quick Create.

    2. In the EADP Quick Create window, select ORDERENT as the database.

    3. From the drop-down for Tables, select LINE_ITEMS. The Internal class name should default to TestLineItemsFromOrdersInternal. Also, ORDERS should automatically be identified as the ruler table if you set up the Object Extender definition correctly.

    4. The New button under Internal Class should now be enabled. Press it.

    5. You will be placed in the Composition Editor for TestLineitemsFromOrdersInternal. There is one icon showing, for the EADPDatabasePart.

    6. Open settings on the EADPDatabasePart.

      1. Select TestOrderEntryAccess as the access set.

      2. From the drop-down for COLUMNS select qvsource (this is the item number). Once you select a column, the "Quick View" button should be enabled. Press it, and you will placed in the "Create Quick View" panel.

        1. You should see the columns for the customer table appear in the "Table Columns" list.

        2. Select DESCRIPTION from the "Table Columns" list. The "Add" button should now be enabled. Press it, and DESCRIPTION be added to the "Quick View Columns" list.

        3. Repeat this for any other columns you want to pull into the quick view (in particular, item number).

        4. The "Okay" button should now be enabled. Press it to save your selections and exit the "Create Quick View" panel.

      3. You should now be back to the "EADP Database Part Setting" panel. The "OK" button should now be enabled. Press it.

    7. When you return to the Composition Editor, save the part, reopen the database settings to reset the base model, and exit.

    4.6.5 Finishing touches

    EADP gives you several ways to customize the way your new part will look.

    4.6.5.1 Column default values

    Open either TestOrdersInteral or TestLineitemsFromOrdersInternal and open settings on the EADPDatabasePart. Since you have already set these parts up, the settings will show the values you have already entered. Choose a column from the list of columns. The "Set Defaults" button will be enabled. If you click this button, you will be presented with the same dialog that VisualAge® uses to customize columns for table parts. However, if you do the customization here, it will take effect on any tables you created by doing a quick form on the resultTable of the internal part, or on focal data if that internal part is the ruler. Try setting up a few defaults now so you can test them when you test the visual parts.

    4.6.5.2 Column Names

    The default for the names of columns (as they appear in the table parts created by doing a quick form), is the data base name for the columns, separated into words and placed in mixed case (this is what VisualAge® uses also). However, EADP allows you to set up the column names globally using VisualAge® NLS facilities. To use these facilities, you must prepare your application to create mpr files (review the procedures in the VisualAge® User Guide). NLS implementation is somewhat different from Release 3 to Release 4. EADP now provides its own facilities for NLS editing to provide consistency (since the indexed message editor is not available in VisualAge® Release 4).

    Before using the EADP NLS facilities, you may also want to use the Script Editor for the internal class to redefine the classNLSGroup and classNLSPoolDictionary public class methods to pick up the values you define for your NLS editor. If you don't redefine these methods, the group and pool will default to the database name followed by "Messages" (e.g. (OrderentMessages).

    To define external names for the internal class and columns, select the Option in the Organizer menu, then select EADP External Names.

    1. Select ORDERENT as the database.

      A list of the internal classes you have defined so far will appear.

    2. Select TestOrdersInternal.

      A list of the columns you have defined (including the quick view and subobject columns) will appear.

    3. Type in an external name for the class (e.g "Orders") and press the "Class Name" button.

    4. Type in an external names for the some of the columns and press the "Column Name" button after each one.

      1. qvsource:cnumb "Customer Id"

      2. qvsource:name "Customer Name"

    4.6.5.3 Object Names

    There are times that EADP needs to display the name of an internal class (for error messages, and also to show which subobjects can be selected for a particular ruler object). The default is to use the internal class name (e.g. TestOrdersInternal). As explained above, you can set the external name for the object using the facilities of the EADPExternalNamesEdit.

    4.6.5.4 Column data types

    In addition to setting the default values for the columns, you can customize the data type. You can create your own custom data types and use them here. One data type that EADP provides is the Coded Data Element. This uses Business Table Factors tables (see 2.3, "Business Factor Tables"). You can use the STATUS column in ORDERS table to see how this works.

    1. Open TestOrdersInternal.

    2. Open Settings on the EADP Database Part.

    3. From the Columns drop down list select STATUS and click the "Column Settings" button.

    4. In the Column Settings dialog, change the data type to "Coded Data Element" and click Customize.

    5. The next window allows you to create or select the Business Factor Table that will control your data element. In the BFT combo box enter the name "StatusBFT" and click "Add BFT".

    6. Once you have created or selected a business factor table, the other keys become enabled. If you wanted to add columns to the BFT you could do it now.

    7. Click the "Edit BFT" button. You will see a table editor that will allow you to add rows (if you wanted to add columns, you would do this in the previous window before editing the BFT). Since you are working with a new BFT, it has only one row and one column.

    8. To add a row, enter a value in the text field over the "Add Row" button. It should now be enabled. Click the "Add Row" button to add a row with the key you have specified.

      1. Add a row with the key value "BACKORDER".

      2. Add a row with the key value "NEW".

    9. Delete the default row.

    10. Select the "NEW" row, and click the "Make Default" key.

    4.6.5.5 Column data names

    One advantage of using Coded Data Elements as a data type is the ability to customize the way that data element will be displayed. To do this,

    1. In the VisualAge® Organizer select the Options menu and then EADP External Names.

    2. Select ORDERENT as the model.

    3. Select TestOrdersInternal as the Internal Class.

    4. Select STATUS as the Column Class.

      If you have customized STATUS as a Coded Data Element, the list of keys will now be available.

    5. Select NEW as the BFT Key.

    6. Type in an external name for the key value (e.g. "New Order").

    7. Press the "Key Name" button.

    4.6.5.6 Derived fields

    Derived fields allow you to display information that is contained in a combination of columns, or spread over several tables. This data can later be used to drive business logic, just as if it existed directly on the database. We will add two cost fields; one to show the cost of each line item, and a second to show the total cost of an order.

    To add the cost of a line:

    1. Open TestLineitemsFromOrdersInternal.

    2. Open Settings on the EADP Database Part.

    3. Select "(computed fields)" from the COLUMNS drop down list.

    4. The QuickView button should be enabled. Press it. The Computed Fields panel will appear.

    5. In the COMPUTED COLUMNS list select (new field). This will be the only entry since you have not defined any computed fields yet.

    6. From the ALL COLUMNS list select quantity. The Add button should be enabled. Press it, and you will see an entry appear as follows in the SOURCE COLUMNS list:
      a:quantity.
      

    7. From the ALL COLUMNS list select price. The Add button should be enabled. Press it, and you will see an entry appear as follows in the SOURCE COLUMNS list:
      b:price.
      

    8. You are now ready to write the formula to calculate the derived field. The rules for writing a formula are as follows:

      1. The source values are a, b, c, or d. You indicate which columns provide source values by adding them to the SOURCE COLUMNS list.

      2. The derived value is x.

      3. Any valid Smalltalk expression can be used within the formula. However, it is advisable to limit yourself to simple manipulations of the source data.

    9. In our case, the derived field is just the product of the two source fields, so the formula is:
      x := a*b
      

    10. Enter the name linecost in the Field Name test area.

    11. The Okay button should now be enabled. Press it to create the derived field.

    12. You can customize the appearance of the computed field. Select (computed fields) and press the Customize button. Then select linecost from the list of columns. You should set it to display in decimal format.

    Now we can add a derived field ordercost to orders.

    1. Open TestOrdersInternal.

    2. Open Settings on the EADP Database Part.

    3. Select "subobject" from the COLUMNS drop down list.

    4. The QuickView button should be enabled. Press it. The Computed Fields panel will appear.

    5. You should see the columns for the line item table appear in the "Table Columns" list.

    6. Select linecost from the "Table Columns" list.

    7. Select "Sum" from the radio button set.

    8. The "Add" button should now be enabled. Press it, and linecost/SUM will be added to the "Quick View Columns" list.

    9. The "Okay" button should now be enabled. Press it to save your selection and exit the "Create Quick View" panel.

    4.7 Creating the list parts

    Now that you have defined the data base parts, you can use visual programming techniques to create the user interfaces. We will begin by creating the visual part just for the ORDERS table, and then add the transition to the list of Line Items.

    4.7.1 Creating the list part for Orders.

    The first step is to establish ORDERS as the top level object in the complex object structure.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestOrdersInternal in the list of internal classes.

    4. In the External radio button set, select List.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestOrdersExternal.

    6. Locate the "resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the resultTable, do a quick form on self, and drop this into the window. This will create the table part needed to display the list.

    8. There are a few extraneous columns you should delete.

    9. Save the part. To test it, select the run option, and when the window comes up, press the Open button. You should see a list of all ORDERS.

    4.7.2 Creating the list part for Line Items.

    The next step is to establish Line Items as a subobject. We will set up the visual part for Line Items, but we have to test from the ORDERS visual part.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestLineitemsFromOrdersInternal. in the list of internal classes.

    4. In the External radio button set, select List.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestLineitemsFromOrdersExternal.

    6. Locate the "resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the resultTable, do a quick form on self, and drop this into the window. The column names should reflect any changes you made using the NLS editor.

    8. Locate the "focalData of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    9. On the focalData, do a quick form on self, and drop this into the window. This will add entry fields for each of the columns in the customer table. You can delete some of them if the window looks too messy. As an alternative, you can do a quick form on each of the attributes of focalData and add them one by one.

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened. You can run the panel in the composition editor to see what the labels will be when the panel is actually opened.

    10. Save the part. You will have to wait until the next step to test it.

    4.7.3 Testing the Orders and Line Items list parts.

    Now we test the connection between the ORDERS and LINE_ITEMS tables. This will allow you to select one row from the ORDERS table, and open a list of Line Items for that order.

    1. Go back the TestOrdersExternal and run the part.

    2. Select one of the orders.

    3. From the File menu select "Open Subobjects".

    4. You will see a panel with the title "Select Subobject". It should show TestLineitemsFromOrdersInternal as the only entry. This is the default name for the subobject; however, you can override it using EADP NLS facilities (see 4.6.5.3, "Object Names").

    5. The Okay button will not be enabled until you select an entry from the list. Select TestLineitemsFromOrdersInternal (or the NLS override for this you set up) and press "Okay."

    6. You should see a list of Line Items for that customer, and the order information in the focal data. You can select another order and open its Line Items also; another window will appear. Note that VisualAge® seems to like to put all the new windows at the same spot on the display, so you may have to move them off one by one to see the next one that comes up.

    4.7.3.1 Testing customizations.

    You can now test any customizations you have made (see 4.6.5, "Finishing touches"). Any changes you made to the column names for display should show up as the titles for the column headings. Also, if you customized the STATUS field as a Coded Data element, you can test that now.

    1. Open a list of Orders.

    2. Tab to a cell under the Status column. It should turn a different color to show that is has been selected.

    3. Move the mouse into the list table and press the right button. You will see a popup menu.

    4. Click on the "Prompt" button.

    5. You will see a list of valid values from the StatusBft which you have created (see 4.6.5.4, "Column data types"). You can change the value in the row by selecting a different value from the list and clicking okay.

    4.7.4 Entry Panels.

    All updates can be made using the list panels described above. However, for larger rows, entry panels may be required as well. EADP provides a convenient mechanism for setting up the entry panels and linking them to the list panels. We will demonstrate this by setting up entry panels for Orders and Line Items.

    4.7.4.1 Creating the entry panel for Orders.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestOrdersInternal. in the list of internal classes.

    4. In the External radio button set, select Entry.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestOrderEntryPanel.

    6. Tear off the resultTable attribute from the EADPInternalPart.

    7. Locate the "currentRow of resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    8. On the currentRow, do a quick form on self, and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened.

    9. Save the part.

    To test the part:

    1. Open a list of Orders (using TestOrdersExternal).

    2. Select one of the rows (use the dropdown list for Release 4).

    3. Press the right mouse button when the mouse pointer is within the table (or at the left hand side of the container).

    4. When the popup menu appears, click the open button.
    You should see the entry panel for ORDERS, with data from the selected row.

    To test updates from the entry panel:

    1. Change the Status field to NEW (or New Order).

    2. Click the apply button on the entry panel.

    3. On the list panel, click the "Refresh" button on the table popup menu. You should see your update reflected in the list.

    4.7.4.2 Creating the entry panel for Line Items.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestLineitemsFromOrdersInternal. in the list of internal classes.

    4. In the External radio button set, select Entry.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestLineitemsFromOrdersEntryPanel.

    6. Locate the "currentRow of resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the currentRow, do a quick form on self, and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

    8. Tear of the focalData attribute from the EADPInternalPart.

    9. Locate the "focalData of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    10. On the focalData, do a quick form on self, and drop this into the window. This will add entry fields for each of the columns in the orders table. You can delete some of them if the window looks too messy. As an alternative, you can do a quick form on each of the attributes of focalData and add them one by one.

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened.

    11. Save the part.

    To test the part:

    1. Open a list of line items (open a list TestOrdersExternal, select Open Subobjects from the File menu, then select TestLineitemsFromOrdersInternal or the name you have used to customize the display of that object).

    2. Select one of the rows.

    3. Press the right mouse button when the mouse pointer is within the table. (or at the left edge of the container).

    4. When the popup menu appears, click the open button.
    You should see the entry panel for Line Items, with data from the selected row.

    4.7.4.3 Customizations on entry panels.

    You can now test any customizations you have made (see 4.6.5, "Finishing touches"). Any changes you made to the column names for display should show up as the labels for the text fields on the entry panel. Note that these show up when the panel is displayed, even though they are not evident in the Composition Editor. If you customized the STATUS field as a Coded Data element, you can test that now.

    1. Open a list of Orders.

    2. Select a row, and click the "Open" button from the table popup menu. This will open the entry panel for that row.

    3. On the entry panel, tab to the Status text field.

    4. Move the mouse into the form area and press the right button. You will see a popup menu.

    5. Click on the "Prompt" button.

    6. You will see a list of valid values from the StatusBft which you have created (see 4.6.5.4, "Column data types"). You can change the value in the row by selecting a different value from the list and clicking okay.

    The same process works on the entry panel for orders. You must place the cursor in the entry field for status to prompt on that field.

    4.7.5 Complex Object Actions.

    You can now exercise the complex object support for copy and delete. In order to verify that these are working properly, you need to set up a visual part TestAllLineItems. Use standard VisualAge processing to add a database part, and to set the query to select all Line Items.

    4.7.5.1 Adding a Line Item for an Order.

    This will show how a line item is set up using the correct order number when is it added to subobject list.

    1. Run TestOrdersExternal.

    2. Select an order, and select the Open Subobjects option from the file menu, then select Line Items from

    3. On the list of Line Items window, click the Add Row choice in the File menu.
    You will see a new row added to the list. Notice that whatever column default values you set up will appear (see 4.6.5.1, "Column default values") and that the order number is set to match the order you selected to find the list of Line Items. If you removed the order number column from the list of Line Items, you can use the TestAllLineItems to verify this (make sure you click Apply first, or the new row won't be on the data base).

    4.7.5.2 Copying Orders and Line Items.

    This will show how all the Line Items for one order are copied to another order.

    1. Run TestOrdersExternal.

    2. Select an order (one which has line items), and select the Copy Row option from the file menu.

    3. Set an order number for the new order, and then click Apply.

    4. Now open the list of Line Items for the new order. They will be identical to the list of Line Items for the old order.

    4.7.5.3 Deleting Orders and Line Items.

    This will show how all the line items for an order are deleted when that order is deleted.

    1. Run TestOrdersExternal.

    2. Select an order (one which has Line Items).

    3. Verify from the TestAllLineItems window that you see the Line Items for that order.

    4. For the selected order, click the Delete Row option on the File Menu, then click Apply. Do NOT click commit.

    5. Now refresh the list for the TestAllLineItems window. The Line Items for the order you selected will be gone.

    6. If you selected one of standard example rows, click Rollback in order list window. This will restore the data which you just deleted.

    4.8 Adding Quick View Navigation and Prompts.

    So far we have created just one transition, from ORDERS to LINE_ITEMS. Now we will add quick views to navigate to the CUSTOMERS and ITEM_CATALOG tables. We already set up the internal parts for these tables so you wouldn't have to backtrack now. All that remains is to add the list panels and entry panels.

    4.8.1 Creating the list part for Customers.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestCustomersInternal. in the list of internal classes.

    4. In the External radio button set, select List.

    5. The External New button should now be enabled. Press it. This will open the compostion editor for a new visual class called TestCustomersExternal.

    6. Locate the "resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the resultTable, do a quick form on self, and drop this into the window.

    8. Save the part. To test it, select the run option, and when the window comes up, press the Open button. You should see a list of all Customers.

    4.8.2 Creating the entry panel for Customers.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestCustomersInternal. in the list of internal classes.

    4. In the External radio button set, select Entry.

    5. The External New button should now be enabled. Press it. This will open the compostion editor for a new visual class called TestCustomersEntryPanel.

    6. Locate the "currentRow of resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the currentRow, do a quick form on self, and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened.

    8. Save the part.

    To test the part:

    1. Open a list of Customers (using TestCustomersExternal).

    2. Select one of the rows.

    3. Press the right mouse button when the mouse pointer is within the table.

    4. When the popup menu appears, click the open button.
    You should see the entry panel for Customers, with data from the selected row.

    4.8.3 Creating the list part for the Item Catalog.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestItemcatalogInternal. in the list of internal classes.

    4. In the External radio button set, select List.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestItemcatalogExternal.

    6. Locate the "resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the resultTable, do a quick form on self, and drop this into the window.

    8. Save the part. To test it, select the run option, and when the window comes up, press the Open button. You should see a list of all entries in the Item Catalog.

    4.8.4 Creating the entry panel for Line Items.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestItemcatalogInternal. in the list of internal classes.

    4. In the External radio button set, select Entry.

    5. The External New button should now be enabled. Press it. This will open the compostion editor for a new visual class called TestItemcatalogEntryPanel.

    6. Locate the "currentRow of resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the currentRow, do a quick form on self, and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened. You can run the panel in the composition editor to see what the labels will be when the panel is actually opened.

    8. Save the part.

    To test the part:

    1. Open a list of entries for the Item Catalog (using TestItemcatalogExternal).

    2. Select one of the rows.

    3. Press the right mouse button when the mouse pointer is within the table.

    4. When the popup menu appears, click the open button.
    You should see the entry panel for Item Catalog, with data from the selected row.

    4.8.5 Quick View Prompts

    Now that the list panels are in place for the quick view tables, you can test out the quick view prompt function.

    1. On the list panel for orders, make a cell in the Customer Number column active by tabbing to it or clicking the mouse within it. It should turn a different color. Now select Prompt from the popup menu. You should see a list of customers. Select one, and press Select on the menu bar. You will see the customer information replaced in the selected row of the orders table. Note that all the quick view columns change value also.

    2. On the entry panel for orders, place the cursor in the text entry field for Customer Number by tabbing to it or clicking the mouse within it. Now select Prompt from the popup menu. You should see a list of customers. Select one, and press Select on the menu bar. You will see the customer information replaced in the selected row of the orders table. Note that all the quick view columns change value also.

    3. On the list panel for line items, make a cell in the Item Number column active by tabbing to it or clicking the mouse within it. It should turn a different color. Now select Prompt from the popup menu. You should see a list of entries for the Item Catalog. Select one, and press Select on the menu bar. You will see the item information replaced in the selected row of the item catalog. Note that all the quick view columns change value also.

    4. On the entry panel for line items, place the cursor in the text entry field for Item Number by tabbing to it or clicking the mouse within it. Now select Prompt from the popup menu. You should see a list of entries for the Item Catalog. Select one, and press Select on the menu bar. You will see the customer information replaced in the selected row of the the item information replaced in the selected row of the item catalog. Note that all the quick view columns change value also.

    4.9 Adding a Selection Popup.

    The sample database is very small, so there is no need to limit the presentation of the top level objects. In a real application, there might be several thousand (or several million) rows in the ORDERS table. A list of orders must select a subset of this table.

    EADP provides a mechanism for adding selection panels to limit the amount of data that is presented. We will show how this works by adding a selection panel for the list of orders.

    4.9.1 Creating the selection panel for Orders.

    The selection panel is very similar to the entry panel. However, it uses the physical database columns. You can also add an extra text field that allows you to directly specify additional selection information.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select ORDERENT as the database.

    3. Select TestOrdersInternal. in the list of internal classes.

    4. In the External radio button set, select Selection.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestOrdersSelection.

    6. Locate the "selectionColumns of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the selectionColumns do a quick form on ORDER_NUMBER (O_NUMB), and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

    8. Repeat this for STATUS and CUSTOMER_NUMBER (C_NUMB).

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened. You can run the panel in the composition editor to see what the labels will be when the panel is actually opened.

    9. Save the part.

    4.9.2 Testing Selection

    To test selection:

    1. Open a list of Orders (using TestOrdersExternal). When you click the Open button, the TestOrdersSelection panel should appear.

    2. Try various combinations:

      1. If you enter nothing on the selection panel and click OK, all the orders will appear.

      2. Enter "O00001" (capital O followed by four zero digits) in the Order Number field. You will just see order 1.

      3. Enter "O%" in the Order Number field. You will see all orders, since they all have this pattern. However, on a real database you could use this to limit the range of orders (e.g. by entering O999% to to get orders O99900 thru O99999).

      4. Enter "C00002" in the Customer Number field. You will see all the orders for customer number 2. You can use prompt in for this field, since it was enabled for quick view.

      5. Use Prompt on the Status field and select either of the values. You will see only orders for that value.

      6. Try a combination of columns. This will restrict the selection to rows that match all the conditions. For example, if you specify "C00002" and "BACKORDER" you will only see the matching entries.

    4.9.3 Allowing more general selection

    You can use the text box to allow more general selection. If you don't want to allow this, delete the text box part that is included in the standard selection part.

    To test general selection:

    1. Open a list of Orders (using TestOrdersExternal). When you click the Open button, the TestOrdersSelection panel should appear.

    2. Type the following statement into the text area:

      ORDER_NUMBER = 'O00001' OR ORDER_NUMBER = 'O00002'.

      (if you are using dBase V)

      O_NUMB = 'O00001' OR O_NUMB = 'O00002'.

    3. Move the cursor into another field to ensure that the text is updated.

    4. Press the OK button. You should see a list that has the first two orders.

    Try combining the selection text data in the fields. If you do this, it is a good idea to enclose the extra selection text in parentheses. For example, if you enter BACKORDER in the Status field and the following statement in the text area:

    CUSTOMER_NUMBER = 'C00001' OR CUSTOMER_NUMBER  = 'C00002'
    
    (if you are using dBase)
    C_NUMB  = 'C00001'  OR C_NUMB = 'C00002'
    

    You will see all the entries for customer 2. If you enclose the statement in parentheses:

    (CUSTOMER_NUMBER = 'C00001' OR CUSTOMER_NUMBER  = 'C00002')
    
    (if you are using dBase)
    (C_NUMB  = 'C00001'  OR C_NUMB = 'C00002')
    

    (CUSTOMER_NUMBER (C_NUMB) you will only see entries that have a status of BACKORDER.

    4.9.4 Using EADPTextHelper to add a text menu

    The EADPTextHelper part provides a quick way to add a popup menu to a selection text window. This section shows how you would add the part to your selection panel (it has already been added, but if you want to do this exercise you can delete it and add it back it).

    1. From the Organizer, select the TestOrderEntryEADP Application.

    2. From the Organizer, select TestOrdersSelection.

    3. In the Composition Editor, using Options.Add Part, add an EADPTextHelper part to the workspace (outside the window).

    4. Make sure the multi-line text is window outside of the form. This is so the the text menu will work correctly.

    5. Connect the self attribute of the multi-line text to the textPart attribute of the EADPTextHelper part.

    To test the menu:

    1. Open a list of Orders (using TestOrdersExternal). When you click the Open button, the TestOrdersSelection panel should appear.

    2. Click the right mouse button in the text area. This will give you a menu that allows to cut, copy. paste, get the text from a file, or save the text to a file.

    3. Enter a selection, and save it to a file before you press the OK button. Be sure to move the cursor off the text area and back on before you save the file, so all your updates are recorded.

    4. Press OK to see the list you have selected.

    5. Press the OPEN button on the list. When the selection popup appears, use the menu to get the file you just saved. It will appear again in the text area.

    4.9.4.1 Using EADPTextHelper in your own parts.

    You can use EADPTextHelper in your own parts to provide text menus. Here are some guidelines:

    1. Make sure that the text part isn't inside another part that already has a popup menu defined.

    2. If you have more than one text area, each one should be connected to its own helper part.

    3. Redefine the finalInitialize method for your visual part to include the following statement:

      EADPTextHelper setupTextFor: self.


    5.0 Setting up a version control sample

    The next example uses the sample data base EADPSAMP which is shipped with the EADP product. Make sure you have this data base installed, and that you have the data base manager opened before you try the examples.

    1. If you are using DB2

      1. You must create the database definition in DB2, and set up a connection for the database. To set up the connection, create the application you will use later and set up a connection there. After you have created the connection, make sure that you connect it so that it shows up in the list of active connections that is displayed in the next step.

      2. From the System Transcript or a Workspace, issue the following command:
        EADPDatabaseSamples installDatabaseForVersionControl
        

        When prompted for a connection, use the one you just set up.

    2. Ff you are using ODBC, make sure that EADPSAMP is defined as a data source for dBase, and issue
      EADPDatabaseSamples installDatabaseForVersionControlForODBC
      

    3. If you are using ODBC, the internal classes should inherit from EADPShortVersionClass instead of EADPApplicationClass.

    5.1 What you will achieve.

    This example will introduce some of the basic concepts of version control, and will demonstrate how EADP manages versions of data. It will familiarize you with the use of version selection objects, and how EADP chooses data at various versions.

    The sample database for version control represents a small engineering records application that allows version controlled changes to part (item) and bill of material data. It has three tables:

    1. AFFECTED_ITEM (VERSION for ODBC users)

      This is the table for the version selection object. It is keyed by EC_NUMBER (EC_NUMB) and ITEM_NUMBER (I_NUMB). EC stands for "Engineering Change". In an engineering records application, an Engineering Change is used to bundle together a group of related changes to different pieces of data. It is an example of a persistent unit of work. The table includes a column VSO_SEQUENCE (VSOSEQ) which is used to select versions of item data.

    2. ITEM_HEADER (ITEMHDR for ODBC)

      This table contains basic information about the item. It is keyed by ITEM_NUMBER. The table includes two columns to enable version control, INSERTSEQ and EXTRACTSEQ (these are called INSERT and EXTRACT for ODBC).

    3. COMPONENT (COMPNNT for ODBC)

      This table sets up the item to item relationship to establish a bill of material (the component items are parts of the assembly). The assembly item is the ITEM_NUMBER column, and the component number is the COMPONENT column (these are both key columns). The table includes two columns to enable version control, INSERTSEQ and EXTRACTSEQ.

    5.1.1 Setting up the Object Extender Definition.

    Begin by importing the schema from the database (call it EADPSAMP) and generating the model from the schema. Note that the model includes root tables and version tables for both Item and Component.

    There are three types of relationships that must be captured. The item is a ruler of the components. However, both the item and component have versions. In order to make the ruler -> subobject relationship a true foreign key relationship, item root and component root tables are introduced. These have the keys of the tables "up to version" as their primary keys. The item root table has item number as its primary key, and the component table has bom number and component number as its primary key. The ruler -> subobject association is a foreign key relationship between the item number and the bom number. Next, there are version control related relationships. The item header has a version relationship with its root. The item header has the same keys as the root, plus the insert sequence number. The same sort of relationship is true for the component and its root. The affected item object acts as a version selection object for the items. It has two fields in its primary key: the item number, and an ec number (ec stands for engineering change, which is the way items are versioned in the real world). From a complex object perspective, the flow of control is from affected item to item header, so the affected item is defined in a ruler -> subobject relationship as the ruler of the item root. However, this is reversed from most ruler -> subobject relationships because the item key (the item number) forms part of the key of the affected item. Finally, there is a quick view relationship from the component number in the component back to the item root.

    The net effect of all these relationships is that almost every attribute in the "data" objects gets replaced with an association. This is because the database is set up with very few data fields; in practice there would probably be twenty others that would be unaffected by all the model activity.

    The following associations must be created:

    1. A ruler to subobject relationship from the item root to the component root (the item root has the role of ruler and the component root has the role of subobject). This replaces the item number attribute in the component root (and forms part of the primary key).

    2. A quick view relationship from the component root back to the item number (make sure the foreign key relationship maps to the component number in the component root). The item root has the role of qvsource, and the component is qvtarget. This replaces the component number in the component root and is the second part of the primary key.

    3. A ruler to subobject relationship from the affected item to the item root. The affected item has the role of ruler, and the item root is subobject. The subobject association replaces item number in the affected item and forms part of the primary key.

    4. A version relationship from the item root to the item header. The item root has the role of root and the item header has the role of version. The root association replaces item number in the item header.

    5. A version relationship from the item root to the item header. The item root has the role of root and the item header has the role of version. The root association replaces item number in the item header.

    6. A version relationship from the component root to the component. The component root has the role of root and the component has the role of version. The root association replaces item number and component number in the component.

    Once you have these set up the classes should have the following primary keys:

    1. Affected item.

      subobject, ec number.

    2. Item root

      item number

    3. Item header

      root, insert sequence.

    4. Component root

      ruler, qvsource

    5. Component

      root, insert sequence

    Note that the combination root -> subobject -> version from item header to component is a fuzzy (many to many) relationship. You do not have to do anything more to establish this within Object Extender. EADP provides all the function necessary to cut through the versions.

    Make sure that you generate the schema from this model, and that all the foreign keys are mapped correctly. Also, you will have to update to mapping model to map all the new associations to the correct database column. Once you have done this you can generate the Object Extender classes (including the service classes).


    5.2 Setting up a version control sample application.

    1. In the VisualAge® Organizer, create a new application (call it TestEADPSamples). Change the prerequisites to EADPBusinessFactorTables and the services application generated for EADPSAMP.

    5.3 Creating the internal parts

    The next step is to create the internal parts to manage the tables and transitions.

    5.3.1 Creating the Application Control Part.

    It is usually good practice set up an application level child of EADPApplicationClass, and have all the internal classes inherit from it. This can be particularly important if you decide later to migrate to using EADP version control.

    1. From the Organizer, select the TestEADPSamples Application.

    2. From the Organizer, create a new nonvisual class. Set its parent to EADPApplicationClass (EADPShortVersionClass for ODBC). Call the new class TestEADPApplicationController.

    3. You will be placed in the Composition Editor for TestEADPApplicationController.

    4. If you want to redefine classNlsGroup and classNlsPoolDictionary from the default values (data base name + messages) you can do it here for all the internal classes in the application:

      1. Switch the Script Editor and choose Class, Public methods.

      2. From the Classes menus, choose Method Visibility, and then to Named Class (EADPApplicationClass).

      3. Select classNLSGroup, and modify the method to point to the group you will use when you use the NLS editor. When you save the method, be sure you specify that the modified code is to be part of your new class (TestEADPApplicationController).

      4. Repeat the process for classNLSPoolDictionary.

    5.3.2 Creating the Affected Item part.

    The first step is to establish Affected Item as the top level object.

    1. Open the EADP Quick Create in the Organizer.

    2. Select EADPSAMP as the database.

    3. Select AFFECTED_ITEM as the table. The Internal class name should default to TestAffecteditemInternal.

    4. Make sure that TestEADPApplicationController is selected as the Base Class.

    5. The New button under Internal Class should now be enabled. Press it.

    6. You will be placed in the Composition Editor for TestAffecteditemInternal. There is one icon showing, for the EADPDatabasePart.

    7. Open settings on the EADPDatabasePart.

      1. From the list of attributes select subobject. The Quick View button should be enabled.

      2. Press the button. On the quick view panel, select item number and any other attributes that you want to see with the affected item. Use FIRST as the summary function.

      3. Press the Okay button to return to Database Settings, and the Okay button there.

    8. When you return to the Composition Editor, save the part, open and close database settings to refresh the base model, and exit.

    5.3.3 Updating the Version Control Part.

    Most of public class methods EADPApplicationClass are there to allow you to adjust the way version control works within your application. Since all of the subobjects of the item will be using the same version control mechanism, it makes sense to add another layer so that these class methods only need to be redefined once. In our example we will be sticking with the defaults for the most part. However, you have considerable flexibility to change the names of the database columns used for sequence numbers, the values of the sequence numbers as they are assigned, etc. The comment for each of these methods explains what it does. You should browse through them before you start to do serious application development.

    For our example, we only need to specify the name of the table which has the Version Selection Object (in this case, AFFECTED_ITEM).

    1. From the Organizer, select the TestEADPSamples Application and TestEADPApplicationController.

    2. You will be placed in the Composition Editor for TestEADPVersionController.

    3. Switch to the Script Editor and choose Class, Public methods.

    4. From the Classes menus, choose Method Visibility, and then Named Class (EADPApplicationClass).

    5. Select vsoTableName, and modify the method to return 'AFFECTED_ITEM'. When you save the method, be sure you specify that the modified code is to be part of your new class (TestEADPApplicationController).

    5.3.4 Creating the Item Header part.

    The next step is to establish Item Header as a subobject of Affected Item. As we will see, the relationship is a special one because Affected Item is a version selection object for the Item Header.

    1. Open EADP Quick Create from the Options menu.

    2. Select EADPSAMP as the database.

    3. Select ITEM_HEADER as the table. The Internal class name should default to TestItemheaderFromAffectitemInternal.

    4. Press the New button.

    5. In the Composition editor, open settings on the database part.

    6. Make sure the "Ruler is VSO" check box is enabled.

    7. Make sure that cascade of promote and undo are enabled.

    8. The "OK" button should now be enabled. Press it.

    9. When you return to the Composition Editor, save the part, reopen and close the database settings, and exit.

    5.3.5 Creating the Component part.

    The next step is to establish Component as a subobject of Item Header. This will include a Quick View back to the Item Header table (using the Component number) to display the component item's name.

    1. Open EADP Quick Create from the Options menu.

    2. Select EADPSAMP as the database.

    3. Select COMPONENT as the table. The Internal class name should default to TestComponentFromItemheaderFromAffectitemInternal.

    4. Press the New button.

    5. You will be placed in the Composition Editor for TestComponentFromItemheaderFromAffectitemInternal. There is one icon showing, for the EADPDatabasePart.

    6. Open settings on the EADPDatabasePart.
        :

      1. From the drop-down for COLUMNS select qvsource. Once you select a column, the "Quick View" button should be enabled. Press it, and you will placed in the "Create Quick View" panel.

        1. You should see the columns for the item header table appear in the "Table Columns" list.

        2. Select NAME from the "Table Columns" list. The "Add" button should now be enabled. Press it, and NAME will be added to the "Quick View Columns" list.

        3. Repeat the process for item number.

        4. The "Okay" button should now be enabled. Press it to save your selections and exit the "Create Quick View" panel.

      2. The "OK" button should now be enabled. Press it.

    7. When you return to the Composition Editor, save the part, reopen and close the database settings, and exit.

    5.4 Creating the list parts

    Now that you have defined the data base parts, you can use visual programming techniques to create the user interfaces. We will begin by creating the visual part just for the Item Header table, and then add the transition to the list of Components.

    5.4.1 Creating the list part for Item Header.

    The list for Item Header will include all versions of the header. That is why we do not include a separate list for Affected Items.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select EADPSAMP as the database.

    3. Select TestItemheaderFromAffectitemInternal. in the list of internal classes.

    4. In the External radio button set, select List.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestItemheaderFromAffectitemExternal.

    6. Locate the "resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the resultTable, do a quick form on self, and drop this into the window.

    8. Save the part. To test it, select the run option, and when the window comes up, press the Open button. You will see a list of all the versions of all the item headers that were loaded in the sample data base.

    5.4.1.1 Testing version control

    It is worthwhile looking at what is displayed, because it illustrates many features of version control. Note that because the VSO Join query was used, all the columns of the AFFECTED_ITEM and ITEM_HEADER table are included in the list. Normally, you would remove many of these columns (for example all the sequence numbers) because they are not of any interest to the end user. However, it is useful to leave them visible for the time being, because they show how the version control mechanism works.

    1. There are four items, P00001 through P00004. Each has one entry in the ITEM_HEADER table (with insert sequence the minimum informal sequence number, and extract sequence number of unextracted).

    2. There are six entries in the AFFECTED_ITEM table, two each for P00001 and P00002 and one each for P0003 and P0004. The first entry for each item has VSO_SEQUENCE of the minimum informal sequence number, and EC_NUMBER of V00001. The second entry has incremented the VSO sequence number by the standard increment, and has EC_NUMBER of V00002.

    3. The entries you see in the list of item headers reflect this. Both entries for the same item number have the same item header data.

    4. Select the row for P00001 at V00001 and change the Name column to ITEM ONE A. Move the cursor off of the column (to make sure that the update registers), and then select File.Apply from the menu bar. Notice that there is still one entry for P00001 in the ITEM_HEADER table, and that the version at V00002 also says ITEM ONE A.

    5. Now select the row for P00001 at V00002 and change the name to ITEM ONE B. Again, move off the name column and select File.Apply. This time the name column at V00001 does not change, but the Extractseq column now has the same value as the VSO_SEQUENCE column in the V00002 row (this means that the data has been extracted by V00002). The Insertseq column in the V00002 row also has this value (this means the data has been inserted by V00002), and the name in that row is now ITEM ONE B.

    6. You can add new versions of the items by using the New Version button in the table popup menu. Try adding several versions, and making changes at only some of them. You will see that the versions that don't have changes attached to them will select the header data that is applicable at the version (the insert sequence is less than or equal to the version VSO sequence, and the extract sequence is greater than the VSO sequence).

    5.4.2 Creating the list part for Components.

    The next step is to establish Components as a subobject.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select EADPSAMP as the database.

    3. Select TestComponentFromAffectitemInternal. in the list of internal classes.

    4. In the External radio button set, select List.

    5. The External New button should now be enabled. Press it. This will open the composition editor for a new visual class called TestComponentFromAffectitemExternal.

    6. Locate the "resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the resultTable, do a quick form on self, and drop this into the window. The column names should reflect any changes you made using the NLS editor.

    8. Locate the "focalData of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    9. On the focalData, do a quick form EC_NUMBER, and drop this into the window. Repeat this for ITEM_NUMBER and NAME.

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened.

    10. Save the part. You will have to wait until the next step to test it.

    5.4.3 Testing the Item Header and Component list parts.

    Now we test the connection between the ITEM_HEADER and COMPONENTS tables. This will allow you to select one row from the ORDERS table, and open a list of Line Items for that version of the item.

    1. Go back the TestItemheaderFromAffectitemExternal and run the part.

    2. From the File menu select "Open Subobjects".

    3. You will see a panel with the title "Select Subobject". It should show TestComponentFromAffectitemInternal as the only entry. This is the default name for the subobject; however, you can override it using VisualAge ® NLS facilities (see 4.6.5.3, "Object Names")

    4. The Okay button will not be enabled until you select an entry from the list. Select TestComponentFromAffectitemInternal (or the NLS override for this you set up) and press "Okay."

    5. You should see a list of Components for that item at that version, with the correct EC number and item number in the focal data.

    5.4.3.1 Testing cross object selection.

    Before modifying the components, take a look at how the component header data is selected using Quick View. Open the list of components for P00001 at both V00001 and V00002. The two lists are identical, and the name Item Two shows up for the name of P00002 as a component in both lists. Close these, change the name of Item Two to ITEM TWO B at V00002. Now open the lists again. All the component data is the same for both lists, but the name for P00002 on the list for V00002 is ITEM TWO B. This is because there is a matching unit of work id (V00002) for the version selection objects for P00001 and P00002. Because this match was found, EADP selects the data for P00002 at the matching version.

    5.4.3.2 Testing version control for subobjects

    Now add or modify component data at V00002. Notice that only the components which were actually modified have their insert and extract sequences changed. (If you want to be sure, you can either use DB2 or open the dbf file to check. Or, you can add insert and extract columns to the list panel).

    5.4.4 Entry Panels.

    All updates can be made using the list panels described above. However, an entry panel for Item Header is needed to take advantage of the Quick Open for the component item.

    5.4.4.1 Creating the entry panel for Item Header.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select EADPSAMP as the database.

    3. Select TestItemheaderFromAffectitemInternal. in the list of internal classes.

    4. In the External radio button set, select Entry.

    5. The External New button should now be enabled. Press it. This will open the compostion editor for a new visual class called TestItemheaderFromAffectitemEntryPanel.

    6. Locate the "resultRow of resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the currentRow, do a quick form on self, and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

    8. Locate the "focalData of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    9. On the focalData, do a quick form on EC_NUMBER and drop this into the window. Note that the columns from AFFECTED_ITEM are all available as focal data for the item header.

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened. You can run the panel in the composition editor to see what the labels will be when the panel is actually opened.

    10. Save the part.

    To test the part:

    1. Open a list of Item Headers (using TestItemheaderFromAffectitemExternal).

    2. Select one of the rows.

    3. Press the right mouse button when the mouse pointer is within the table.

    4. When the popup menu appears, click the open button.
    You should see the entry panel for Item Header, with data from the selected row.

    To test updates from the entry panel:

    1. Change the Name to Entry Name.

    2. Click the apply button on the entry panel.

    3. On the list panel, click the "Refresh" button on the table popup menu. You should see your update reflected in the list.

    5.4.4.2 Quick Open of version controlled data.

    Now that you have created the entry panel for Item Header, you can see how Quick Open works for version controlled data. Open the list of Components for P00001 at both V00001 and V00002, and then do a Quick Open on the item data for component P00002. Notice that it is selected at V00001 from the V00001 panel, and V00002 from the V00002 panel. Quick Open will open the same version of data that Quick View selects for presentation.

    5.4.4.3 Creating the entry panel for Components.

    1. From the Organizer menu, select Options, then EADP Quick Create.

    2. Select EADPSAMP as the database.

    3. Select TestComponentFromItemheaderFromAffecteditemInternal. in the list of internal classes.

    4. In the External radio button set, select Entry.

    5. The External New button should now be enabled. Press it. This will open the compostion editor for a new visual class called TestComponentFromItemheaderFromAffecteditemEntryPanel.

    6. Locate the "resultRow of resultTable of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    7. On the currentRow, do a quick form on self, and drop this into the form (note that it must be dropped into the form and not into the window. This is to allow popup menus to work on the entry panel).

    8. Locate the "focalData of EADPInternalPart" (this is located near the bottom of the Composition Editor free form surface).

    9. On the focalData, do a quick form on EC_NUMBER and drop this into the window. Repeat this for ITEM_NUMBER and NAME.

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened. You can run the panel in the composition editor to see what the labels will be when the panel is actually opened.

    10. Save the part.

    5.5 Creating, Deleting and Undoing Versions

    This section introduces some of the more advanced features of version control. Each new version allows you to isolate changes and protect the data you have entered at other versions. As long as the version is in informal status, you can back out the work you have done at that version by deleting the version or by using the undo function to reverse the changes to a particular object. These examples do not require you to build any new panels. Instead, they will guide you through functions that you would perform as a user of the application that you have already built.

    After doing these exercises, be sure to use the rollback function to restore the database to its original state. If you forget to do this, you can restore the database by reinstalling it. To reinstall, execute the following command in the System Transcript or a Workspace:

    EADPSampleDatabases loadDatabaseSamples.
    

    5.5.1 Creating a New Version.

    1. Open the TestItemheaderFromAffectitemList panel. You can do this quickly by executing selecting the part in the Organizer and pressing the Run button.

    2. Select the row for Item P00001 at EC V00001.

    3. Press "New Version" on the popup menu for the table part.

    4. A new row will appear with all fields filled in except the EC number. Enter V00003 in this field (be sure to move the cursor off the field so the update is recorded).

    5. Select "Apply" from the menu bar.

    You can now use the new version to modify header data, or to add, change or modify component data. There are some specific updates will we make in the next sections to demonstrate the undo and delete functions.

    5.5.2 Using the Undo Function.

    The undo function is used to back out the changes made by a particular version. It is invoked automatically when the version is deleted, but you can also use it on selected rows to restore the data for just that row.

    5.5.2.1 Undo of Modified Data.

    The simplest undo is of data that was modified at a the version.

    1. On the TestItemheaderFromAffectitemExternal panel change the Name of Item P00001 at V00003 to Item One C. Be sure to move the cursor off of the updated cell before you apply the change.

    2. Now open the list of components for P00001 at V00001 and make the following updates:

      1. Delete the component with component number P00003.

      2. Change the quantity of the component with component number P00003 to 3.

      3. Add a component with component number P00004.

    3. Now undo the changes to the item header:

      1. Select the row for Item P00001 at V00003.

      2. On the popup menu for the table part, click "Undo Row".

      3. On the popup menu for the table part, click "Refresh". You will see that the name has been restored to its original value, and the the insert and extract sequence numbers show that the data is no longer affected by V00003.

      4. Refresh the component list panel. Notice that it is unchanged. Undo does not cascade if modified data is removed.

    4. Now undo the added component:

      1. On the component list panel, select the component with component number P00004.

      2. Select "Undo Row" from the popup menu.

      3. Refresh the panel. Notice that the row is missing. Since the version added the row, undoing it removes the row completely.

    5. Now undo the deleted component. To do this, we have to be able to see it again.

      1. From the popup menu, select "Refresh for Undo". Notice that the deleted component appears. This is because it was extracted (not physically deleted). If the component had been inserted by V00003 and then deleted, undo would not be able to restore it.

      2. Select the deleted component, and press "Undo Row" on the popup menu.

      3. Refresh the list. The deleted row has been restored.

    5.5.2.2 Undo of Inserted Data.

    When undo is applied to data that was created by the version, that data is physically deleted. The processing is the same as if the row was deleted (using Delete Row). This will cascade the delete to any subobjects.

    We do not have data set up to completely demonstrate how this works (it is likely that your application may never be complicated enough to fully exploit this feature). However, we can demonstrate delete cascade by deleting the second version of an item header. Before starting this exercise, be sure you have restored the data to its original state.

    1. Open the TestItemheaderFromAffectitemExternal panel. you can do this quickly by selecting the part in the Organizer and pressing the Run button.

    2. Select the row for Item P00001 at EC V00002.

    3. Open the subobject list for components at EC V00002. Do this before deleting the header data so that you can see how the subobjects are affected.

    4. Select File.Delete Row on the header list panel, then select apply.

    5. Refresh both the header list panel and the component list panel

    6. Note that component list panel is now empty.

    7. Now select "Refresh for Undo" on the on the popup menu for the table part.

    8. The components will all appear again. However, they cannot be restored here, because there is no version of header data at V00002.

    5.5.2.3 Undo of Extracted Data.

    This continues the previous example. When the undo action is executed for extracted data, the action cascades to restore any subobjects that were also extracted.

    1. On the item header list panel, select "Refresh for Undo" from the popup menu.

    2. The deleted row (item P00001 at EC V00002) should reappear.

    3. Select the row, and "Undo Row".

    4. Now refresh both the item and component list panels. Notice that the deleted data has been restored on both panels.

    5.5.3 Deleting a Version.

    Deleting a version removes all the affects of that version, and also deletes the version selection object for that version. Be sure that you restore the data to its original state by using the Rollback button after completing this exercise.

    1. Add a new version V00003 to item P00001 (see 5.5.1, "Creating a New Version."). Use the new version to modify data for both the header and components.

    2. Open the component list panel at version V0002. Notice that the components that you modified at V0003 reflect this with their extract sequence numbers.

    3. Now select item P00001 at V00003 on the header list panel, and select "Delete Version" from the popup menu.

    4. Select Apply.

    5. Refresh the component list panel at V00002. The components that were extracted by V00003 are now unextracted.

    6. Refresh the item header list panel. The version V00003 is gone.

    The version is completely removed. Refresh for undo will not restore it on the list panels.


    5.6 Creating a new item.

    Since an item is version controlled, creating a new item requires creating a new version for it also. This is accomplished by adding a row to the affected item list panel, and entering the new version name there. Then open subobjects (the item header) for this row. At the item header list panel type in the item name and item number, then press the commit button. Both the affected item and the item header are held within the scope of the same Object Extender transaction, so both are committed together.


    6.0 Adding Application Logic

    Despite the growing popularity of visual tools, there is still a tendency to think that business logic belongs back on the mainframe. However, the EADP provides you with tools to create and organize the business layer of your application. This is fully integrated with the complex object support and version control support layers discussed so far.


    6.1 Business Factor Tables

    We saw an example of a business factor table in 4.6.5.4, "Column data types" That example created a BFT that just had the key column. Now we will add an extra column so we can use it to drive business logic. The following assumes that you already have done the customizations described there.

    1. Open TestOrdersInternal.

    2. Open Settings on the EADP Database Part.

    3. From the Columns drop down list select STATUS and click the "Column Settings" button.

    4. In the Column Settings dialog, make sure the data type is "Coded Data Element" and click Customize.

    5. In the next window, "StatusBFT" should be preselected.

    6. Add a new column called TestOkay.

    7. Click the "Edit BFT" button. You will see a table editor that will allow you to modify the rows. Since you added a column to an existing BFT, you will see the default value of asterisk in the new column for all the rows. You should see two rows, one for BACKORDER and one for NEWORDER.

    8. Set the value of TestOkay to "Y" for the NEWORDER row and to "N" for the BACKORDER row. Be sure to move the cursor off of the modified field before exiting the panel.

    9. Use the "Okay" button to exit the panel.

    6.2 Setting Triggers

    We will set up several types of triggers to illustrate some of the possibilities. In your own application, you should pay special attention to how triggers are set and what they mean. Even though the same data condition may drive several decisions, it may not be an identical trigger condition. If the rules for one decision change, they may or may not be reflected in the other rules associated to the same trigger. A good test is whether or not you can give an external business meaning to the trigger itself. The same reasoning applies to columns in the business factor tables, since these will be used for trigger definition. The examples below cover the mechanics of trigger definition, but they do not fully capture the business analysis needed to do this wisely.

    6.2.1 Setting a Simple Trigger

    The simplest trigger just evaluates a single column in a database row.

    1. From the Organizer menu select Options, and then EADP Trigger Settings.

    2. Create a new trigger called State Trigger, with symbol stateTrigger.

    3. This is a simple trigger, so it needs a database row and a formula.

      1. From the dropdown list of models, select ORDERENT.

      2. You now have a choice of tables in the dropdown list. Select Orders.

      3. You now have a choice of columns. Select qvsource.

      4. The Add Quick View button should be enable. Press it.

      5. On the quick panel,select state, and press the Okay button.

      6. The Formula must be a Boolean that evaluates against the column value, which is passed in as x. In this example, we will test if the State is New York. States are stored in abbreviated format, so the formula is:

        x = 'NY'

        Note the single quotes around the NY, because it is a string field. The formula is evaluated as a Smalltalk method and should follow Smalltalk conventions.

      7. The File.Save Trigger button should be enabled. Click it to save the trigger.

    6.2.2 Setting a Simple BFT Trigger

    This slightly more complicated example uses a BFT column instead of the direct value of the column. This provides a degree of isolation in the formula.

    1. From the Organizer menu select Options, and then EADP Trigger Settings.

    2. Create a new trigger called Order Trigger, with symbol orderTrigger.

    3. This is a simple trigger, so it needs a database row and a formula.

      1. From the dropdown list of models, select ORDERENT.

      2. You now have a choice of tables in the dropdown list. Select ORDERS.

      3. You now have a choice of columns. Select STATUS.

      4. Since STATUS is a Coded Data Element, you must choose a BFT column. Choose TestOkay.

      5. The Formula must be a Boolean that evaluates against the column value, which is passed in as x. In this example, we will test if the TestOkay is "Y", so the formula is:

        x = 'Y'

      6. The File.Save Trigger button should be enabled. Click it to save the trigger.

    6.2.3 Setting a Simple Derived Trigger

    This example uses a derived column. The ability to use derived columns in triggers allows you to make more complex business decisions.

    1. From the Organizer menu select Options, and then EADP Trigger Settings.

    2. Create a new trigger called Order Cost Trigger, with symbol orderCostTrigger.

    3. This is a simple trigger, so it needs a database row and a formula.

      1. From the dropdown list of models, select ORDERENT.

      2. You now have a choice of tables in the dropdown list. Select ORDERS.

      3. You now have a choice of columns. Select SUB*LINE_ITEMS:COMPUTED:LINE_TOTAL/SUM.

      4. The Formula must be a Boolean that evaluates against the column value, which is passed in as x. In this example, we will test if the total cost of the order is less that $50, so the formula is:

        x < 50

      5. The File.Save Trigger button should be enabled. Click it to save the trigger.

    6.2.4 Setting a Compound Trigger

    Any set of simple or compound triggers can be combined to make a compound trigger. However, you have to make sure that all the triggers can be evaluated together, and also that the evaluation does not create a loop. Here is an example of a compound trigger:

    1. From the Organizer menu select Options, and then EADP Trigger Settings.

    2. Create a new trigger called Order New York Cost Trigger, with symbol orderNYCostTrigger.

    3. This is a compound trigger, so it does not need a database row and a formula.

    4. You need to specify which triggers will be combined to make up the compound trigger, and how they will be evaluated. The collection of subtriggers can either be ANDed or ORed to give the final result, and each subtrigger can be evaluated as either TRUE or FALSE.

    5. Set the And/Or toggle switch to And.

    6. Set the True/False toggle switch to True.

    7. From the dropdown list of subtriggers select stateTrigger.

    8. The Add Subtrigger button should be enabled. Press it and the trigger should be added to the subtrigger list.

    9. Repeat the process for orderCostTrigger.
    The compound trigger you have created will be true if the customer lives in New York and the cost of the order is less than $50. If this is not what you need (for example, you wanted to select customer in New York but cost greater than $50), you can easily change the logic selection. Select the stateTrigger:true line in the list of subtriggers, and press the Change Subtrigger button. The line changes to stateTrigger:false. The trigger will now select orders with customer living outside of New York and cost $50 or higher.

    6.3 Adding Business Rules

    Business verifications are associated to a particular database table. They can be defined to execute when any of the following events occur:

    1. Add

    2. Change

    3. Update

    4. Delete

    5. Promote

    Note that the "Promote" event requires that the table is version controlled.

    6.3.1 Adding Business Rule Example

    We will add an example of a rule that checks if the customer lives in New York, and the price of the order is greater than $50 (this uses the trigger defined in 6.2.3, "Setting a Simple Derived Trigger"). The rule will be defined to prevent change or deletion of the order.

    Business rules are defined using the Business Rules Editor

    1. In the VisualAge® Organizer, make sure that TestEADPSamples is the default application.

    2. From the Organizer menu select Options, and then EADP Edit Rules.

    3. From the dropdown list for Database, select ORDERENT.

    4. From the dropdown list for Table, select ORDERS.

    5. In the Rule box, type the name of the rule:

      New York cost rule.

    6. In the Rule Text box, type a description for the rule:

      Check that cost is less than fifty dollars if the customer lives in New York.

    7. In the Symbol box, type the symbol for the rule. This will be used to generate a Smalltalk instance method, so it should follow Smalltalk naming conventions:

      nyCostRule

    8. In the Message Number box, type the symbol you will use for the error message. You should define the message using the EADP Error Message NLS editor (see 6.3.2, "Adding Error Messages"). If you don't (for this exercise), nothing terrible will happen. Instead of getting the real error message, you will get an EADP message that the error message could not be found. Note that the error message symbol should start with a capital letter (e.g. MyErrorMessage). If it doesn't, you won't be able to add the rule.

    9. From the dropdown list above the Add Trigger button, select orderNYCostTrigger. This has already been set up as a compound trigger to check both conditions. Press the Add Trigger button.

    10. The trigger will be added to the list of Selection Triggers. These can be manipulated just like the sub triggers defined in 6.2.3, "Setting a Simple Derived Trigger").

    11. Select "On Change".

    12. From the File menu, select Save Rule.

      If the Save option is not enabled, check that you have entered all the data mentioned above. Also, make sure that the rule symbol starts with a small letter, and the message symbol starts with a capital letter. Both of these should be all alphabetic without imbedded blanks.

    To test the rule.

    1. In the Organizer, select TestCustomersExternal and press the Run button.

    2. Select OK in the selection popup to get all customers.

    3. In the list of Customers, add a customer A0001 with NY as the state of residence.

    4. Select Apply to save the value.

    5. Close the Customer list.

    6. In the Organizer, select TestOrdersExternal and press the Run button.

    7. Select OK in the selection popup to get all orders.

    8. Select an order with total price greater than $50.

    9. Place the cursor in the Customer number cell for that row and select Prompt from the popup menu.

    10. In the list of Customers, select A0001 (the one that lives in New York).

    11. Now select Apply on the list of Orders.

    You will see the error message associated with the rule (or an message that the error message could not be found).

    Try adjusting the amount in the trigger, and see what happens. All the orders have a cost greater than fifty dollars, but only one has a cost greater that seventy dollars.

    6.3.2 Adding Error Messages

    Error messages are defined using EADP NLS facilities.

    1. In the VisualAge® Organizer menu select Options and then EADP Error Messages.

    2. Select ORDERENT as the database.

    3. The messages list will show all the message names you have defined when you set up rules for that database.

    4. Select a message from the list.

    5. Type in message text and press the "Update Message Text" button.

    6. Type in help text and press the "Update Help Text" button.

    6.4 Adding Business Policies

    Business policies let you organize your business rules. Use this function to define and organize the business policies for your application. You can attach rules to each policy to provide a higher level of organization for the rules. This can be useful when a single policy requires implementation by many rules for different database tables.

    If a policy changes, you can use this function to find the rules that were associated to the old policy.

    6.4.1 Adding Business Policies Example

    We will create a policy for the "New York Cost" rule.

    1. Be sure you have connected to the database.

    2. In the Organizer menu, select Options, and then EADP Edit Policies.

    3. Enter a policy name and description.

    4. Use File.Save to save the policy.

    5. The Add Rule button should now be enabled. Press it.

    6. The next window allows you to select a rule to add to the policy. Rules are organized by database and table:

      1. From the list of databases select ORDERENT.

      2. From the list of tables select ORDERS.

      3. From the list of rules select New York cost rule.

    7. Press Okay to add the rule to the policy.

    You can see information about the rule by selecting the rule in the list of rules for the policy, and pressing Open Rule. This will bring up the Edit Rules panel, with that rule selected.


    7.0 Generating Reports and Batch Files

    EADP offers a quick and convenient way to generate reports and batch files. You can use a sample of the file you want to create to produce templates. Specialized classes within EADP called macro classes are then used to fill in the variable data. For the most part, you can use macros that are already available.


    7.1 Creating Report Templates

    The example given here is a very simple one. In a real situation, you might begin with an example of your output as a model for the template file. You can use the file options in the Template Editor to bring in a file to get started (or you can file out and file in the templates if you want to use a more powerful editor during the template creation).

    Here are some basic steps to prepare a set of templates for a report:

    7.1.1 Opening the Template Editor for Reports

    1. In the Organizer menu, select Options, and then EADP Edit Templates.

      This will open the Template Editor. All templates are stored as entries in Smalltalk dictionaries. The Template Editor allows you to edit these dictionary entries as if they were ordinary text files, and to file them in and out of sequential files.

    2. Select "ORDERENT Reports" from the drop down list next to the "Select Dictionary" button, and press the button.

    3. You are now ready to create the templates needed for the report.

    7.1.2 The Structure of a Template

    A template is a piece of text with imbedded keywords. The keywords are delimited by dollar signs. For example:

    text1.. $keyword1$ text2.... $keyword2$... etc.

    A template can span multiple lines of text. However, a special keyword $+$ at the end of a line indicates that a new line character should not be added when the template is processed.

    When a template is processed, the text outside the keyword is passed along as in into the output stream. The text inside a keyword is evaluated according to the following rules:

    1. The text up to the first comma is checked to see if it matches the name of a VisualAge® class. If it does, the "macro" class method of that class is invoked. One of the passed parameters is the rest of the text for the keyword (this is parsed by each macro).

      The macro we will be using for reports is ReportMacro. Its macro method expects the rest of the keyword string to be in the format "(template name),(internal class name)".

      1. The template name must be provided. It indicates which template will be used to process the next stage of the report.

      2. The ReportMacro expects the "current row" to be passed as a parameter. If the internal class name is not included, it will process everything in the template based on the current row. If the internal class name is included, the class should be a subobject for the table for the current row. The current row is used to select rows of the subobjects, and then each of these is used to process the template. We will use this technique to start with a row from the customer table, and use it to select all orders for the customer. Then each row from the orders table will be used to select line items for that order.

    2. If the first part of the text is not that name of a class, it should match the name of a variable is the substitution list. For reports, this means that it should match an attribute name for the current row being reported (these are the data base column names and any additional columns added through the Quick View functions). A quick way of finding out which names to use is to open the Composition Editor for the entry panel for the data base, and do a Quick Form on the currentRow part.

      Any text after the comma is assumed to be formatting information:

      1. The first piece is the name of the class which will do the formatting (for example PadRightFormat). If this is omitted, no special formatting is done. The data appears just as it would on the list or entry panels.

      2. If there is more data (delimited by a second comma) this is passed to the formatting class. For example, the length of the field is passed to PadRightFormat.

    7.1.3 Creating a Template to Start a Report

    The report will be initiated from the list of orders. It will use the executeReport method on the EADPApplicationClass, which passed the current row to the template processor. The first step is to write a template to start processing.

    1. Open the EADP Template Editor from the Options menu in the Organizer.

    2. Select ORDERENTReports as the Template Dictionary.

    3. In the Template Editor, enter the following in the Template Name box:

      StartReport

    4. In the Template Editor, enter the following in the Text Area box:
      Title: Order Report
      $ReportMacro,OrderReport$
      

      This template will put out the line "Title: Order Report" at the head of the report. The keyword then invokes ReportMacro, passing the current row, and telling it to use the OrderReport template. The macro method of the ReportMacro class will prepare a variable list based on the column data in the current row before processing the template.

    5. VisualAge® only recognizes changes in a field AFTER the cursor leaves that field. Click the mouse in both the Template Name box and the Text Area box to make sure the changes are recorded.

    6. From the File menu, select Save Template. You should see StartReport added to the list of templates.

    7.1.4 Adding a Template for Order Data

    The next step is to add a template to process the order data. This will have substitution keywords for the order columns we want on the report, and a macro keyword to bring in all the line items the order.

    1. In the Template Editor, enter the following in the Template Name box:

      OrderReport

    2. In the Template Editor, enter the following in the Text Area box:
      Order #: $ordernumber$  Status: $status$,PadLeftFormat,12$
      Customer: $qvsource:customernumber$
      Line Items for Order
      $Reportmacro,LineItemReport,TestLineitemsFromOrdersInternal$
      
      (if you are using dBase V)
      Order #: $onumb$  Status: $status,PadLeftFormat,12$
      Customer: $qvsource:cnumb$
       
      Line Items for Order
      $ReportMacro,LineItemReport,TestLinesFromOrdersInternal$
      

      This template will put out the information for the indicated fields, using the values in the current row. A keyword then invokes ReportMacro, passing the current row, and telling it to use the LineItemReport template. Since TestLineitemsFromOrdersInternal is included, the current row will be used to select line items matching the order. The macro method of the ReportMacro class will loop through the list of rows prepare a variable list based on the column data on each row before processing the template.

    3. VisualAge® only recognizes changes in a field AFTER the cursor leaves that field. Click the mouse in both the Template Name box and the Text Area box to make sure the changes are recorded.

    4. From the File menu, select Save Template. You should see OrderReport added to the list of templates.

    7.1.5 Adding a Template for Line Item Data

    The final step is to add a template to process the line items. This will have substitution keywords for the order columns we want on the report.

    1. In the Template Editor, enter the following in the Template Name box:

      LineItemReport

    2. In the Template Editor, enter the following in the Text Area box:
      Line #: $orderlinenumber$ Item: $qvsource:itemnumber$ $+$
      Qty: $quantity,PadNumericFormat,8$ Price: $price,PadNumericFormat,8$
      
      (if you are using dBase V)
      Line #: $lnumb$ Item: $qvsource:inumb$ $+$
      Qty: $quantity,PadNumericFormat,8$ Price: $price,PadNumericFormat,8$
      

      This template will put out the information for the indicated fields, using the values in the current row.

    3. VisualAge® only recognizes changes in a field AFTER the cursor leaves that field. Click the mouse in both the Template Name box and the Text Area box to make sure the changes are recorded.

    4. From the File menu, select Save Template. You should see LineItemReport added to the list of templates.

    7.1.6 Testing the Report

    In order to test the report, you must add a Report action.

    1. Open the Composition Editor for TestOrdersExternal.

    2. Select a push button part from the palette, and add it to the Window. Change the name to Report.

    3. Connect the clicked event of the Report Button to the executeReport action of the EADPInternalPart.

    4. Save the updates.

    To run the report:

    1. In the Organizer, select TestOrdersExternal and press the Run button.

    2. Open the list of orders.

    3. Select an entry and press the Report button.

    4. You will see the Report Dialog window.

    5. From the Template dropdown list select StartReport.

    6. Press the "Process Report" button.

    7. The Report Results window displays your report.

    8. The Save button will allow you to save the report to a sequential file.

    8.0 The EADP Help Facility

    EADP provides a help facility that is implemented within VisualAge®, and so is platform independent. It lets you visually create the help for your panels.


    8.1 Enabling EADP help for panels.

    You enable a visual part for EADP help by adding the EADPHelpHelper:

    1. Add the EADPHelpHelper part outside the Window part.

    2. Connect the visual part to the EADPHelpHelper part as follows:

      1. Connect self to the visualPart attribute of the helper part.

      2. Connect the aboutToOpenWidget action to the startHelpConnections action of the helper part.

    8.2 Enabling EADP help for messages.

    In order to use EADP help for messages, use the following command to issue the message:

    EADPMessageDisplay showMessage:
    (self getMRIString: MessageSymbol group:#EADPMessages)
     forSymbol: 'MessageSymbol'.
    
    where MessageSymbol is the message symbol in the NLS editor. If there are substitutions in the message, you handle them in the same way that you usually do for getMRIString: group:. The entire substituted message string should be passed to showMessage: forSymbol:. A string value should be passed as the second parameter (note that MessageSymbol is in quotes so it is the literal string that is being passed).

    8.3 Adding new help

    1. In order to add new help, you must place the help parts in learn mode. From the System Transcript or a Workspace issue the following command:
      EADPHelpClass learnMode: true.
      

    2. To place the help back into browse mode, issue:

      EADPHelpClass learnMode: false.

    3. Now press function key 1 at the place where you want to add the help. The EADP Help window will appear in edit mode.

    4. There are two pull-down lists. The one on top gives the names of the current panel and any of its parents that have been defined by EADP or by you.

    5. The second list show the part you selected when pressed the function key, and any of its parent parts (as widgets).

    6. The first part or panel that had an existing help file is selected. If there is no help yet for the panel, the Window part will be selected.

    7. Add help for the Window part first. This is used as panel level help.

    8. You can add help for each of the entries in the parts list.

    9. Use the Save and Refresh buttons to save the help, and to refresh the text box if you change parts. Make sure that you move the cursor away from the text box before saving the text.

    You can also add help using the EADP Help Editor. In the Organizer menu, select Options and then EADP Edit Help.

    The top list shows panels parts, with the class name of the panel. EADPMessageDisplay is a particularly useful choice, because the message helps are stored here.

    The second list shows the help parts, using the internal names. The message helps are shown here using the name you passed as the second parameter to showMessage: forSymbol.

    To add a new help (this can be particularly useful for messages if it is difficult to get the message to display)

    1. Select the panel part.

    2. Type the part name in the text box above the dropdown list of parts.

    3. Type the help text in the multiline edit box. Be sure to move the cursor out of the box before you save the help.

    4. Select File.Save Help File.
    You can also revise existing help texts be selecting an existing part from the list and editing it.

    8.4 Using EADP help

    When using EADP help, you should make sure the help is not in learn mode (issue the command EADPHelpClass learnMode: false). When you bring up the EADP Help panel in browse mode you will see the following buttons:

    1. Panel Help

      This will open the help that you added for the Window part of the panel. This should be a good general description of what that panel does.

    2. EADP Help

      This opens the EADP Help Browser, with the current part and panel selected.

      1. You can use the list of subparts to browse help for other components of the same panel.

      2. You can use the list of panels to access any other help that has been defined using the EADP help facility.

    3. VisualAge® help.

      This opens the table of contents for the standard VisualAge help facility.

    4. Help text can be processed for translation using VisualAge® facilities. The EADPHelpMriHandler has methods to add and remove the help text from the standard mpr files:

      1. addHelpToMriEditForApp:

        This method will add the help files for an application (e.g. TestEADPSamples) to the standard indexed messages file for that application. You can use standard NLS techniques to generate mpr and translation files including the help text. The constant name for each help entry identifies the panel name and part name to assist in translation,

      2. removeHelpFromMriFEditForApp:

        This method will back out the help text entries.

      3. helpDictionaryFromMriForDictClass:

        This method creates a new help dictionary from the help entries in the mpr file. This would be used to load translated help.

        If you are running in a single language environment you can change the language for the help by executing the following statements in a Workspace.

        1. EADPDictionariesClass helpDictionary: (EADPHelpMriHandler helpDictionaryFromMriForDictClass: EADPDictionariesClass) TestEADPSamplesDictionariesClass helpDictionary: (EADPHelpMriHandler helpDictionaryFromMriForDictClass: TestEADPSamplesDictionariesClass).

          (You would substitute the name of your own application),

        The language is changed once in the build time environment, and the translate help is packaged as a dictionary in each runtime image (so that all runtime images have the same language for the help files).

        If you are running in a multiple language environment, and you want each runtime image to pick up a different language for the help files, issue the following statement in a Workspace.

        EADPApp doNls: true.

        When EADP generates the startup code for your runtime application it will add the statements described above.


    9.0 Packaging a Runtime Image

    Before attempting to package a runtime image you should read the instructions in the Users Guide. Note that eadpea30.mpr needs to be copied to your runtime directory, along with any the file you may have created for the order entry application.

    Object Extender adds the complication that the services application and the model application which it generates are prerequisites of the view application that you have created. Make sure that both these applications have been versioned, and that the services application is in the list of prerequisites. Also, make sure that you didn't store your model in the same application that was used to create the runtime classes. The model storage class is an "edit" type part, and it will prevent your runtime image from executing.

    You must also make sure that the appropriate database application (AbtDbmCliBaseApp or AbtDbmOdbcApp) is included as a prerequisite.

    VisualAge® is a little too aggressive when it prunes the runtime image. Also, it does not provide a method to activate the datastore. EADP provides the class method setupConnectionForApp: forClass: in EADPApp to correct this.

    1. To use this method, set up a new visual part TestOrdersentMainMenu for TestOrderEntryEADP.

    2. Make sure TestOrderEntryEADP is the selected application, and execute the method as follows (from a Window):
      EADPApp setupConnectionForApp: TestOrderEntryEADP forClass:
      TestOrdersentMainMenu
      

      This will generate two instance methods in TestOrdersentMainMenu,

      1. eadpAddToRuntimeImage

        You don't have to do anything with this method because the generated code for connectToDb calls it.

      2. connectToDb

        The generated code here will connect you to the database and set up the queries in the runtime image. It also calls eadpAddToRuntimeImage, which calls enough methods to make sure everything EADP needs gets packaged. If you have added new indirect classes or methods to your application (other than what EADP generates for you), you may need to include more dummy code in one of these two methods.

        This method needs to be connected to a push button, as described below, so that VisualAge® knows that it is a live method in the runtime image, and starts to follow its trail to bring in other classes and methods.

    3. In the script editor for TestOrdersentMainMenu add two new instance methods:
      openCustomers
         TestCustomersExternal new openWidget
       
      openOrders
         TestOrdersExternal new openWidget
      

    4. In the Composition Editor for TestOrderentMainMenu:

      1. Add a "Connect to Database" push button and connect its "clicked" event to connectToDb.

      2. Add an "Open Customers" push button and connect its "clicked" event to openCustomers.

      3. Add an "Open Orders" push button and connect its "clicked" event to openOrders.

    5. Save the part.

    6. You are now ready to generate the runtime image for TestOrderEntryEADP. The EADP prerequisite should be EADPBusinessFactorTables. You can use the Prerequisites option in the Applications menu selection on the Organizer to adjust the prerequisites.

      1. In the Organizer, select TestOrderEntryEADP.

      2. From the menu, select Applications.Prerequisites. This will display a list of the currently defined prerequisites.

      3. If you see EADPApp, do the following to change the prerequisite to EADPBusinessFactorTables.

        1. Press the change button.

        2. You will see a list on the left of available applications. Select EADPBusinessFactorTables.

        3. Press the "right arrow" button to move this application over to the list of prerequisite applications.

        4. Press the okay button to return to the first dialog box.

        5. Press okay again to update the prerequisites.

      4. Make sure that the services application and the database application as described above are prerequisities.

    10.0 Adding Web Support

    EADP lets you create Web forms using the same internal parts that you set up in the previous exercises. Since the internal parts act as a controller layer, there is very little extra work involved in setting up the Web forms.

    Before you begin this section, make sure that you have the Web Connection feature properly installed. You should make sure that the "Hello World" sample comes up as described in the Web Connection user manual.

    This section assumes that you have already built the Order Entry application described earlier in this manual. What you will do now is set up Web pages to present that application.

    The EADP Web parts follow a slightly different pattern than the visual parts. There are four Web parts that are used to build the forms:

    1. EADPWebList

      This part is used to present top level objects. It includes selection fields and selection text at the top of the form to limit the selection of objects.

    2. EADPWebSubList

      This part is used for lists of subobjects. It is similar to the EADPWebList, but is does not include the selection text or the Open button.

    3. EADPWebSelectList

      This part is used for selection after a quick view prompt. It is like the EADPWebList (it includes selection fields), but the only action allowed is selection of a row.

    4. EADPWebEntry

      This form is used for updates (tabular update is not possible for the Web forms). It also support prompts for quick view and bft fields.

    Selection on the Web forms has to be more explicit than on the visual parts (since there is no way to keep track of cursor position). On the list parts, a drop-down list of the keys for the rows is used to select which row to work with. Similarly, a drop-down list of subobjects is provided. On the entry panel, a drop-down list of the fields that can be prompted is provided. All panels have a drop down list of subparts to invoke help for that subpart.

    To demonstrate how this all works, we will build the forms to present the Order Entry application.


    10.1 Create a Web application.

    In order to keep prerequisites isolated for packaging, it is better not to mix visual parts and Web parts in the same application. Create a new application, TestOrdersWebEADP, and make sure that is has both EADPWebSupport and TestOrderEntryEADP as prerequisites.


    10.2 Creating the list form for Orders.

    The first step is to establish ORDERS as the top level object in the complex object structure.

    1. From the Organizer menu, select Options, and then EADP Quick Create.

    2. Select ORDERENT as the database, and TestOrdersInternal as the internal class.

    3. In the Web radio button set, select list, and the press the New button.

    4. The Composition editor will open for TestOrdersWebList.

    5. Find the "queryPart of EADPInternalPart".

    6. On the queryPart, do a quick html on resultTable self, and drop this into the bottom of the HTML page (underneath the HTML form).

    7. You can also add selection fields.

      1. Find the "selectionColumns of queryPart of EADPInternalPart".

      2. Do a Quick HTML on the selectionColumns, and select ORDER_NUMBER (O_NUMB). Drop this into the from area of the HTML Page, just under the horizontal rule under the selection text.

      3. Repeat this for C_NUMB and STATUS.

    8. Save the part. To test it, you will have to bring up the Web browser and point it at the new class TestOrdersWebList. When the form comes up, press the Open button. You should see a list of all ORDERS. You can use the selection fields and text to limit selection of the orders.

    Notice that if you used the NLS editor to update the names of columns, the NLS names show up when you run the form.


    10.3 Creating the list form for Line Items.

    The next step is to establish Line Items as a subobject. We will set up the visual part for Line Items, but we have to test from the ORDERS visual part.

    1. From the Organizer menu, select Options, and then EADP Quick Create.

    2. Select ORDERENT as the database, and TestLinetemsFromOrdersInternal as the internal class.

    3. In the Web radio button set, select list, and the press the New button.

    4. The Composition editor will open for TestLineitemsFromOrdersWebList.

    5. Find the "queryPart of EADPInternalPart".

    6. From the Organizer, select the TestOrdersWebEADP Application.

    7. On the queryPart, do a quick html on resultTable self, and drop this into the bottom of the HTML page (underneath the HTML form).

    8. Find the "focalData of EADPInternalPart".

    9. On the focalData, do a quick html on ORDER_NUMBER (O_NUMB) and drop this into the form area of the HTML page (a section marked by horizontal rules has been set up to receive the focal data). Repeat this for any other fields you want to include as focal data,

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened.

    10. You can test this part by bringing up the for for Orders. It should show line items in the list of subobjects to select. Press the Open Subobjects button, and you should see a list of line items for the selected row.

    10.4 Creating the entry form for Orders.

    1. From the Organizer menu, select Options, and then EADP Quick Create.

    2. Select ORDERENT as the database, and TestOrdersInternal as the internal class.

    3. In the Web radio button set, select Entry, and the press the New button.

    4. The Composition editor will open for TestOrdersWebEntry.

    5. Find the "queryPart of EADPInternalPart".

    6. On the queryPart, do a quick html on resultRow, and drop this into the form area HTML page (underneath the horizontal rule under the Apply button).

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the form is run.

    7. Save the part.

    To test the part:

    1. Open a list of Orders (using TestOrdersWebList).

    2. Select one of the rows.

    3. Press the Open Row button.
    You should see the entry form for ORDERS, with data from the selected row.

    To test updates from the entry panel:

    1. Change the Status field to BACKORDER (or New Order).

    2. Click the apply button on the entry panel.

    3. On the list form, click the "Refresh" button on the table popup menu. You should see your update reflected in the list.

    10.5 Creating the entry form for Line Items.

    1. From the Organizer menu, select Options, and then EADP Quick Create.

    2. Select ORDERENT as the database, and TestLineitemsFromOrdersInternal as the internal class.

    3. In the Web radio button set, select Entry, and the press the New button.

    4. The Composition editor will open for TestLineitemsFromOrdersWebEntry.

    5. Find the "queryPart of EADPInternalPart".

    6. From the Organizer, select the TestOrdersWebEADP Application.

    7. On the queryPart, do a quick html on resultRow, and drop this into the form area HTML page (underneath the horizontal rule under the Apply button).

      Note that panel shows the database column names as labels in the Composition Editor. Do not change these. They will be replaced by the external names (with any customizations you have made) when the panel is opened. You can run the panel in the composition editor to see what the labels will be when the panel is actually opened.

    8. Save the part.

    To test the part:

    1. Open a list of line items (open a list TestOrdersWebList, and the open a subobject),

    2. Select one of the rows.

    3. Press the Open Row button.
    You should see the entry form for Line Items, with data from the selected row.

    10.6 Creating the selection list form for Customers.

    The next step is to set up CUSTOMERS so it can be used for a quick view prompt.

    1. From the Organizer menu, select Options, and then EADP Quick Create.

    2. Select ORDERENT as the database, and TestCusomersInternal as the internal class.

    3. In the Web radio button set, select Quick Selection, and the press the New button.

    4. The Composition editor will open for TestCustomersWebSelectList.

    5. Find the queryPart of EADPInternalPart.

    6. On the queryPart, do a quick html on resultTable self, and drop this into the bottom of the HTML page (underneath the HTML form).

    7. You can also add selection fields.

      1. Find the resultRow of queryPart.

      2. Do a Quick HTML on the resultRow, and select CUSTOMER_NUMBER (C_NUMB). Drop this into the from area of the HTL Page, just under the horizontal rule under the selection text.

      3. Repeat this for any other fields such as name and address that you might want to use to limit selection.

    8. Save the part.

    9. To test the part:

      1. Open an entry form for Orders.

      2. In the drop-down list of prompt fields, select customer number (this only works of you have set up quick views for customer on the order internal part).

      3. Press the PROMPT button. You should see the selection list of customers.

      4. Enter selection data and press the OPEN button. You will see a list of customers limited by your selection.

      5. Select a row from the drop-down list and press the SELECT button. You should see the entry form for ORDERS, with the customer number updated by your selection.

    Notice that if you used the NLS editor to update the names of columns, the NLS names show up when you run the form.


    10.7 Using customized reports

    Once you have created the Web parts, you can use the customized report facility that is included as part of EADPWebSupport.

    10.7.1 Starting customized reports

    Before starting the report, you can use selection criteria on the list panel to limit which orders will be reported. You can also use the Hide button to hide selected rows. These rows are not deleted from the database, but they will not be included in the report.

    The Customize button on TestOrdersWebList will bring up the report customization form. This form lets you select which fields you want to include on the report. You can also create new quick view or derived subobject fields here and add them to the report.

    You can work your way through several levels of the complex object structure within the same report. At each level you can select fields to include on the report. You can also limit selection of subobjects by adding additional selection criteria.

    10.7.2 Selecting fields to report.

    In the list of Available Columns, select Order Number. Press the Add Report Column Button. You will see Order Number added to the list of Report Columns.

    10.7.3 Creating quick view fields

    Just as when you created quick views for the internal class, you select a quick view table and the column from that table you want to add as a quick view. For the example, select CUSTOMERS as the table and Zip Code as the column.

    You can choose an external name for the new fields as you create them. For the example, type "Customer Zip Code" in the External Name text box.

    Now press the Add to Report Button next to the list of Available Quick View Columns.

    10.7.4 Creating subobject fields

    Just as when you created summary fields for the internal class, you select a subobject table and the column from that table you want to summarize. For the example, select LINE_ITEMS as the table and Item Number as the column. (Note -- you need to select the table and press the select table button to refresh the list of available summary columns).

    You must choose a summary function. For reports, an additional summary function ALL is supported. This will report all the values for all the rows of the subobjects for each ruler (e.g. all the line items for each order) separated by semicolons. Use the ALL function for this example.

    You can choose an external name for the new fields as you create them. For the example, type "All Items" in the External Name text box.

    Now press the Add to Report Button next to the list of Available Quick Views.

    10.7.5 Adding sort columns

    You can change the way the report results are sorted by choosing sort columns. For example, select Customer Number in the list of available columns and press the "Add Sort Column After" button. If you want to add another sort columns (for example Status) you can do this by selecting that column from the list of available columns. If you select a column from the list of currently defined sort columns, the "Add Sort Column Before" or "Add Sort Column After" buttons will place the new sort column before or after the one you just selected. You can also add more sort columns at the subobject level (so you can sort by item number, then customer number).

    10.7.6 Reporting subobjects

    You can include subobjects in the report as well. If your report includes several rows of a subobject for each ruler (for example several line items for each order), the fields you have selected for the ruler will be repeated. To move down in the report structure, select a Subobject table (from the list of subobjects) and press the "Drill Down" button. The same form will appear, but the list of Available Columns will be those for the subobject. You can add additional fields at this point. For the exercise, add Item Number to the report.

    10.7.7 Saving the report

    You can save the report at this point before you run it. To save the report, type a name for the report (e.g. TestSub), and press the Save button.

    10.7.8 Formatting the report

    Now press the Finish button to run the report. The next panel is the Report Parameters form. This allows you to select a title for the report, and to provide some formatting information. The table alignment allows you to decide if the table that shows the report body will be right, left, or center aligned (not all Web browsers support this tag, so this may not work for you). The Break Point selection shows a list of the object types included in the report (in this case Orders and Line Items). If you select "None" all the fields will be included in the same row. If you select Orders, the report fields for Orders will be shown as header fields, with the report fields for lines reported in tabular form. If you break at line items, all the fields will be shown as header fields, with a new report section for each line item.

    The "Do page break selection" lets you choose to adjust the output so that each report section begins on a new page. If the tabular portion (lines for an order) overflows the page length, a break is made and the header data is repeated on the next page. The lines per page entry lets you adjust the page length for your particular printer. Web browsers (at the time this is written) do not have an inherent capability to do paging, so you will have to adjust the lines per page to get the breaks adjusted for your particular environment.

    10.7.8.1 Viewing the report

    The Report button brings up the report as you formatted it. You can print the report now, using the print facility for the browser. If you don't like the way the report looks, you can use the Back function of the browser to get back to the Report Parameters panel. You need to do this in any case to get back to the Return button on that panel, which will bring you back to the first list panel for the application.

    10.7.8.2 Updating from the report results

    One useful feature of the report facility is the ability to select subobjects which meet additional search criteria (for example for can find all lines for all orders where the item number is P00001). To take advantage of this, the Update button on the Report Parameters panel brings up a list that allows selection of a row. When a row is selected, the entry form for the lowest level object related to that row comes up.

    10.7.8.3 Tabular and global updates.

    This panel also supports tabular and global update. Some data is presented in data entry fields. These can be updated; save the updates by pressing the apply button. There is also a list of fields that allow global update at the top of the panel. Select a field, enter the new value, and press the Global update button. The new value will replace the old one in all the rows that allow update.

    The rules to permit update are as follows:

    1. The field must be at the bottom level of the selection.

    2. It cannot be a derived field or a key field.

    3. The row must allow update.

    4. If the row is version controlled, the selection must be at the latest version.

    10.7.9 Retrieving and modifying the report

    From the main list of orders, hit the Customize button. Before doing this, if you reported orders you didn't want to see, you could hide rows,

    In the Report Customization Form, select TestSub from the list next the Get Customization button, and hit that button. The form will be filled in with the customization that you saved. Before you run the report you can modify these settings. For this example we will limit the selection of subobjects.

    10.7.10 Limiting subobject selection.

    Select Line Items as the subobject table and press the Subobjects button. This will bring you to the customizations you have already defined for the Line Items. You can add a selection criteria to limit which line items show up in the report.

    The list of selection columns shows the name and data type of the "real" database columns that can be used to formulate a SQL selection statement. If you are not familiar with SQL, you should review rules for select statements before trying to use this feature.

    For the exercise, we will limit the report to line items with a particular part number. Type the following statement in the text box and press the Limit Selection button:

    ITEM_NUMBER =  "P00001"
    
    Note: ODBC users will see I_NUMB as the column name and should use this name in the selection statement.

    Now press Report to view the report. Note that only a few rows are reported now. Orders which do not have a line item for that item number are not reported at all.


    10.8 Packaging the Web Application.

    Packaging of Web applications is a little different because they do not have a visual part. Make sure that you have structured your applications into a runtime application and a web application. You w have to set the prerequisites for the runtime application as described above in 9.0, "Packaging a Runtime Image" ' You should review the section in the Web Connection users manual before attempting this exercise.

    10.8.1 EADP support for Web packaging.

    As for the visual packaging, EADP provides a special method to make sure that all the EADP features get included in the package.

    1. In the Organizer, make sure that you have selected TestOrdersWebEADP.

    2. Open a new workspace and issue the following command:
    EADPApp setupWebConnectionForApp: TestOrdersWebEADP
    withInternalApp: TestOrderEntryEADP
    

    This will generate three class methods in TestOrdersWebEADP

    1. runtimeStartUp

      This method has code similar to the connectToDb method. It calls eadpAddToRuntimeImage.

    2. eadpAddToRuntimeImage

    3. exiting

    You don't have to do anything additional because the runtimeStartUp and exiting methods are already called by the system. However, for Release 5.0, you must decide whether you want to have the monitor come up in the runtime image. If so, you need to include AbtRunHtmlPageApp as a prerequisite ofyour Web application.

    10.8.2 Customized reports.

    If for some reason you want to include report customizations that you made in the build time image, issue the following command from a workspace

    TestOrdersWebEADPDictionariesClass saveCustReportDictionary.
    

    This will generate a file called ORDERENT.DCT that will be placed in your "current" VisualAge® directory (the one that has your build time image). Copy this file over to the runtime directory, The naming conventions used here are:

    1. For the dictionary class, the application name plus "DictionariesClass".

    2. For the file name, the name of the database, with an extension of DCT.

    10.9 Version controlled Web presentation.

    Building a Web presentation for the version controlled example follows the same steps. You can use the EADP Quick Create to create the Web parts in exactly the same way as for the Order Entry example. However, the parts will look somewhat different because they include buttons for the appropriate version control actions.

    When you open a version of an item, you will be placed directly in the entry page for the item. To create a new item, first create a new affected item by using the add row button in the affected item list page. You will be placed in the entry form for the affected item. Add the version number there, then press the "Drill Down" button. This will place you in the entry form for the item. Add the item name and number, then press the Save button. This will save both the affected item and the item header information.


    11.0 Using EADP Interface Support.

    Quite often you will need to convert data from an existing application, or be able to update your application from interface files sent by another application. A typical way this data is passed is in a text file.

    EADP Interface support provides a quick way to set up structures to parse the text file, extract the data out of it, map it to the internal structure that you have defined for your application, and update your database. It uses much the same structure of templates and macros as 7.0, "Generating Reports and Batch Files", but in reverse. The templates are used to describe the structure of the incoming file, and the macros are used to extract data from the input file and place it in internal storage.


    11.1 Defining Interface Templates.

    Interface templates are defined using the Template Editor as described in 7.1.1, "Opening the Template Editor for Reports". However, you select "ORDERENT Interfaces" as the working dictionary.

    The structure of the templates needs to be adjusted to map to the structure of the incoming file. There are two issues here,

    1. Selection of which template to use to parse a particular record in the in input file.

    2. Selection of data from within each record and mapping it to an internal structure.

    11.1.1 Mapping templates to records.

    This is done using a naming convention for the template. The first element of selection is the choice of the dictionary for the template. This tells which database the template should process.

    1. If all the records in the interface file go to a particular table, the name of that table should form the first part of the name of the file. This is useful if the interface is broken up into several different files (for example, if a database unload on the existing data was used to create the interface files, typically there will be one file for each table in the source database).

      In this case, all the records in the file have the same type. The template name would end with an asterisk (e.g. ORDERS*) to indicate that no further checking should be done to determine which template to use for the record.

    2. If there is a mix of record types within the interface file, it is assumed that the first part of the records contains an identifying symbol that indicates the record type. This symbol becomes part of the template name for the template used to parse that record:

      1. If a table name is used, the symbol part of the name would be appended to the table name.

      2. If no table name is used, the symbol name becomes the full template name. For example, the interface file might have records that start with <1> for orders, and <2> for line items. The templates to parse these records would be named <1> and <2>.

    11.1.2 Setting up a template to parse a record.

    Within the template, macros and literals are used to describe the record structure.

    1. Macros are used to extract data from the current position in the record. As with the templates described in 7.1.1, "Opening the Template Editor for Reports" the macros are delimited by dollar signs.

    2. Within the keyword delimited by the dollar sign, parameters are separated by commas.

      1. The first parameter is always the macro name. The additional parameters depend on the macro. Three commonly used macros and their parameters will be described here:

        1. EADPColumnInterface

          This is the most commonly used macro to extract data. By specifying the name of the internal class and the column name, you can indicated how to map the data at that point in the record. The following parameters are added, separated by commas:

          1. Internal class name

            The name of the internal class (e.g. TestOrdersInternal) to process the update. This may be omitted, if a keyword specifying a standard internal class for the template has been provided (this is done using the EADPTableType macro).

          2. Column name

            The database name for the column

          3. format

            This is the name of the formatting class that will be used to convert the data before it is used. If omitted, the default class EADPInterfaceFormat is used (this class just passes back the data as is without additional formatting).

          4. format pattern

            If provided, this contains additional parameters for the formatting class.

          5. length

            If length is included, it is used to determine how much of the input record to read in to get the column data.

        2. EADPTwoColumnInterface

          This lets you specify a second internal calls name (after the first and before the column name). This is so the same piece of data can be mapped to two different internal classes. This is useful if the table structure you have set up for you database is different from the table structure in the source database that is being interfaced. A real life example is a database for IBM legal that included data for folders in boxes. The source database replicated the "box" data in each row. The target database breaks this data into "box" data and "folder" data (processed by LegalBoxInternal and LegalFolderInternal). However, the key data (the box number) needs to go both places, and so is handled by EADPTwoColumnInterface.

        3. EADPTableType

          This is used to specify a default internal class, so that the class name doesn't need to be specified.

      2. Specifying parsing information

        The position of the macro keywords within the template specifies where they are to extract data from the interface record. There are two ways that the position within the record can be described:

        1. If the interface record uses delimiters to separate the fields, the delimiters are included in the template as literals (outside the macro keywords.

        2. If the interface record has fixed length fields (so that the position, not a delimiting literal, is used to specify where a field starts), then each macro keyword needs to include a length parameter.

    11.1.3 An interface example.

    Here is an example of an interface file that adds a new order with two line items:

    <1>O00007;C00001;BACKORDER;
    <2>O00007;1;P00001;5;1.25;
    <2>O00007;2;P00001;10;1.25;
    

    Note that there are two record types, <1> for orders and <2> for line items. Also, a semicolon is used to delimit fields.

    Two templates are used to parse the input file. The first template is named <1> and looks like this:

    <1>$EADPTableType,TestOrdersInternal$
    $,,onumb$;
    $,,qvsource:cnumb$;
    $,,status$;
    

    The second template is named <2> and looks like this

    <2>$EADPTableType,TestLineitemsFromOrdersInternal$
    $,,ruler:onumb$;
    $,,lnumb$;
    $,,inumb$;
    $,,quantity$;
    $,,price$;
    

    11.2 Running interfaces.

    Once you have set up the templates for the interface, you use EADPInterfaceView to processing the interface file. This example shows how to run the file described here. To run the example, you must set up the templates using the template editor, and save the interface file.

    1. In the VisualAge Organizer, select EADPInterfaceApp as the application, and EADPInterfaceView as the part.

    2. Press the Run button on the toolbar.

    3. The EADPInterfaceView window will appear.

      1. Select the interface file you have saved and open it. It should appear in the text box (you can type the file in here directly if you have not previously saved it on your system).

      2. From the dropdown list of models, select ORDERENT.

      3. Do not specify a table name, since the naming convention for the templates does not use a table name.