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.
3.0 Designing your application to use the EADP
4.0 Setting up a sample complex object
5.0 Setting up a version control sample
7.0 Generating Reports and Batch Files
11.0 Using EADP Interface Support.
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.
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.
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:
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®.
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.
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.
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.
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.
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.
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:
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).
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.
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.
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.
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:
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.
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:
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).
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.
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.
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.
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.
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.
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.
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).
This selects the version with insert sequence less than or equal to the selection sequence and extract greater.
This is like the Applicable, but it also includes data that was extracted by the version.
This finds all rows which match the logical key.
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.
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.
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.
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.
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").
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.
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.
A business rule is an executable part of the application. Each rule is defined by the following:
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.
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.
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.
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.
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.
A template is a fragment of text with substitutions. The substitution areas are delimited by dollar signs. For report generation, you can:
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.").
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.
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.
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.
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.
The first example uses the sample data base ORDERENT which was shipped with the VisualAge® product in Version 2. To install this database
EADPDatabaseSamples installOrderentSampleData.
When prompted for a connection, use the one you just set up.
EADPOdbcOrderEntrySamples installDatabase
Before installing the database, you must set up ORDERENT as a dBase data source using the ODBC administrator.
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.
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:
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.
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).
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:
Make sure that primary keys are set up as follows:
order number
ruler, line number
customer 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.
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).
The first step is to establish Customers as a top level object so that it can be linked to Orders using quick view.
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.
The next step is to establish Orders as the top level object in the complex object structure ORDERS -> LINE_ITEMS.
Now that a top level object has been set up for Orders, you can add Line Items as a subobject.
EADP gives you several ways to customize the way your new part will look.
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.
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.
A list of the internal classes you have defined so far will appear.
A list of the columns you have defined (including the quick view and subobject columns) will appear.
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.
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.
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,
If you have customized STATUS as a Coded Data Element, the list of keys will now be available.
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:
a:quantity.
b:price.
x := a*b
Now we can add a derived field ordercost to orders.
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.
The first step is to establish ORDERS as the top level object in the complex object structure.
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.
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.
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.
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.
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.
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.
To test the part:
To test updates from 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.
To test the part:
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.
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.
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.
This will show how a line item is set up using the correct order number when is it added to subobject list.
This will show how all the Line Items for one order are copied to another order.
This will show how all the line items for an order are deleted when that order is deleted.
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.
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.
To test the part:
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.
To test the part:
Now that the list panels are in place for the quick view tables, you can test out the quick view prompt function.
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.
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.
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.
To test 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:
(if you are using dBase V)ORDER_NUMBER = 'O00001' OR ORDER_NUMBER = 'O00002'.
O_NUMB = 'O00001' OR O_NUMB = 'O00002'.
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.
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).
To test the menu:
You can use EADPTextHelper in your own parts to provide text menus. Here are some guidelines:
EADPTextHelper setupTextFor: self.
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.
EADPDatabaseSamples installDatabaseForVersionControl
When prompted for a connection, use the one you just set up.
EADPDatabaseSamples installDatabaseForVersionControlForODBC
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:
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.
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).
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.
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:
Once you have these set up the classes should have the following primary keys:
subobject, ec number.
item number
root, insert sequence.
ruler, qvsource
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).
The next step is to create the internal parts to manage the tables and transitions.
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.
The first step is to establish Affected Item as the top level object.
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).
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.
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.
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.
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.
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.
The next step is to establish Components as a subobject.
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.
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.
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.
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).
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.
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.
To test the part:
To test updates from the entry panel:
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.
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.
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.
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.
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.
The simplest undo is of data that was modified at a the version.
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.
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.
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.
The version is completely removed. Refresh for undo will not restore it on the list panels.
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.
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.
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.
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.
The simplest trigger just evaluates a single column in a database row.
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.
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.
x = 'Y'
This example uses a derived column. The ability to use derived columns in triggers allows you to make more complex business decisions.
x < 50
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:
Business verifications are associated to a particular database table. They can be defined to execute when any of the following events occur:
Note that the "Promote" event requires that the table is version controlled.
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
New York cost rule.
Check that cost is less than fifty dollars if the customer lives in New York.
nyCostRule
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.
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.
Error messages are defined using EADP NLS facilities.
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.
We will create a policy for the "New York Cost" rule.
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.
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.
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:
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.
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:
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)".
Any text after the comma is assumed to be formatting information:
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.
StartReport
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.
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.
OrderReport
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.
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.
LineItemReport
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.
In order to test the report, you must add a Report action.
To run the report:
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.
You enable a visual part for EADP help by adding the EADPHelpHelper:
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).
EADPHelpClass learnMode: true.
EADPHelpClass learnMode: false.
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)
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:
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.
This opens the EADP Help Browser, with the current part and panel selected.
This opens the table of contents for the standard VisualAge help facility.
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,
This method will back out the help text entries.
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.
(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.
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.
EADPApp setupConnectionForApp: TestOrderEntryEADP forClass: TestOrdersentMainMenu
This will generate two instance methods in TestOrdersentMainMenu,
You don't have to do anything with this method because the generated code for connectToDb calls it.
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.
openCustomers TestCustomersExternal new openWidget openOrders TestOrdersExternal new openWidget
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:
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.
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.
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.
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.
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.
The first step is to establish ORDERS as the top level object in the complex object structure.
Notice that if you used the NLS editor to update the names of columns, the NLS names show up when you run the form.
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.
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.
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.
To test the part:
To test updates from 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.
To test the part:
The next step is to set up CUSTOMERS so it can be used for a quick view prompt.
Notice that if you used the NLS editor to update the names of columns, the NLS names show up when you run the form.
Once you have created the Web parts, you can use the customized report facility that is included as part of EADPWebSupport.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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:
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.
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.
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.
As for the visual packaging, EADP provides a special method to make sure that all the EADP features get included in the package.
EADPApp setupWebConnectionForApp: TestOrdersWebEADP withInternalApp: TestOrderEntryEADP
This will generate three class methods in TestOrdersWebEADP
This method has code similar to the connectToDb method. It calls eadpAddToRuntimeImage.
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.
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:
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.
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.
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,
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.
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.
Within the template, macros and literals are used to describe the record structure.
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:
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).
The database name for the column
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).
If provided, this contains additional parameters for the formatting class.
If length is included, it is used to determine how much of the input record to read in to get the column data.
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.
This is used to specify a default internal class, so that the class name doesn't need to be specified.
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:
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$;
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.