VisualAge For Cobol
VisualAge For Cobol
January 1996
IBML
SG24-4606-00
International Technical Support Organization
January 1996
Take Note!
Before using this information and the product it supports, be sure to read the general information under
“Special Notices” on page xiii.
This edition applies to Version 1, Release 1, of IBM VisualAge for COBOL for OS/2 (Part number 28H2177) for use
with OS/2 2.1 or higher. The examples in this edition require a Corrective Service Disk (CSD) that is planned to
be applied to IBM VisualAge for COBOL for OS/2 Version 1, Release 1 product in the first quarter of 1996.
Order publications through your IBM representative or the IBM branch office serving your locality. Publications
are not stocked at the address given below.
An ITSO Technical Bulletin Evaluation Form for reader′s feedback appears facing Chapter 1. If the form has been
removed, comments may be addressed to:
When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any
way it believes appropriate without incurring any obligation to you.
This document was written for anyone expecting to be involved in the production
of object-oriented COBOL programs and presumes knowledge of COBOL.
(349 pages)
Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
How This Document is Organized . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Related Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
International Technical Support Organization Publications . . . . . . . . . . . xvii
ITSO Redbooks on the World Wide Web (WWW) . . . . . . . . . . . . . . . . xviii
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Chapter 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1 The Importance of OO COBOL . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Purpose of Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Assumption Concerning Audience . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Manual Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Chapter 2. OO Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1 The Direction of Computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 IBM′s Leading Role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Application Development Problems . . . . . . . . . . . . . . . . . . . . . . . 9
2.4 OO Claim to Answers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 OO Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6 OO Review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.7 OO History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Chapter 5. Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.1 Evolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.2 Dangers and Difficulties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
5.3 IBM Internal Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.4 Timescales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Chapter 6. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.1 Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.2 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.3 Business Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.4 Code Creation and Processing . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Chapter 7. Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
7.1 Class Definition Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.2 Class Definition Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Chapter 8. Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.1 Method Definition Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
8.1.1 Method Definition Statements . . . . . . . . . . . . . . . . . . . . . . . . 66
Chapter 9. Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9.1 Client Program Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9.2 Client Definition Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
9.3 Client Definition Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
9.4 Object Reference Statement Details . . . . . . . . . . . . . . . . . . . . . . 71
9.5 Interacting with Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Contents vii
Appendix B. Example Two Source Code . . . . . . . . . . . . . . . . . . . . . 191
B.1 Example Two − UserInterface Class Code . . . . . . . . . . . . . . . . . . 191
B.2 Example Two − WineCase Class Code . . . . . . . . . . . . . . . . . . . . 193
B.3 Example Two − Wine Client Class Code . . . . . . . . . . . . . . . . . . . 196
B.4 Example Two − NewCase Class Code . . . . . . . . . . . . . . . . . . . . 197
B.5 Example Two − OldCase Class Code . . . . . . . . . . . . . . . . . . . . . 197
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
Information in this book was developed in conjunction with use of the equipment
specified, and is limited in application to those specific hardware and software
products and levels.
IBM may have patents or pending patent applications covering subject matter in
this document. The furnishing of this document does not give you any license to
these patents. You can send license inquiries, in writing, to the IBM Director of
Licensing, IBM Corporation, 500 Columbus Avenue, Thornwood, NY 10594 USA.
The information contained in this document has not been submitted to any
formal IBM test and is distributed AS IS. The use of this information or the
implementation of any of these techniques is a customer responsibility and
depends on the customer′s ability to evaluate and integrate them into the
customer′s operational environment. While each item may have been reviewed
by IBM for accuracy in a specific situation, there is no guarantee that the same
or similar results will be obtained elsewhere. Customers attempting to adapt
these techniques to their own environments do so at their own risk.
IBM
Related Publications
The publications listed in this section are considered particularly suitable for a
more detailed discussion of the topics covered in this document.
• IBM COBOL for MVS and VM - Programming Guide, SC26-4767
• SOMobjects for MVS - User ′ s Guide, GC28-1545
• SOMobjects for MVS - Class Library Reference, SC28-1546
• IBM COBOL Set for AIX - Programming Guide, SC26-8423
• IBM COBOL Set for AIX - Getting Started, GC26-8425
• IBM VisualAge for COBOL for OS/2 - Programming Guide, SC26-8419
• IBM VisualAge for COBOL for OS/2 - Getting Started, GC26-8421
IBM employees in the USA may order ITSO books and CD-ROMs using
PUBORDER. Customers in the USA may order by calling 1-800-879-2755 or by
faxing 1-800-445-9269. Most major credit cards are accepted. Outside the
USA, customers should contact their local IBM office. For guidance on
ordering, send a note to BOOKSHOP at DKIBMVM1 or E-mail to
[email protected].
Preface xvii
ITSO Redbooks on the World Wide Web (WWW)
Internet users may find information about redbooks on the ITSO World Wide Web
home page. To access the ITSO Web pages, point your Web browser to the
following URL:
http://www.redbooks.ibm.com/redbooks
Acknowledgments
This project was designed and managed by:
Joe DeCarlo
International Technical Support Organization, San Jose Center
Richard Mascall
IBM United Kingdom
Rob Pittman
IBM North America
Thanks to the following people for the invaluable advice and guidance provided
in the production of this document:
George Forshay
Services Development, Santa Teresa Laboratory, IBM Software Solutions
Ira Sheftman
COBOL Development, Santa Teresa Laboratory, IBM Software Solutions
This chapter explains the present and future of object-oriented programming and
COBOL.
If COBOL has dominated the past, and still dominates the present, what will
dominate the future? Many commentators point to object-oriented programming
(OO) as the direction of the industry. By ″industry″ we mean all computing: from
the largest mainframe, to workstations and the smallest personal computing
accessories through tiny real-time devices not conventionally thought of as
computers.
Does this mean COBOL is dying and that its usefulness is coming to an end?
On the contrary, IBM′s latest enhancements to the COBOL family will move OO
from the highly promising to the widely utilized.
The significance for IBM is that whichever company can provide that significant
combination of COBOL and OO on all computer platforms will be assured of an
immensely powerful and successful position. This is illustrated in Figure 1.
The syntax of the new language facilities are not explained in Part one but is
covered in Parts two and three. However, you will be in an excellent position to
move on to learning the HOW using this manual as a solid base.
The new COBOL topic forms the heart of this manual and it contains examples
using IBM′s System Object Model (SOM), which is a major differentiator of IBM′ s
OO approach from others.
Chapter 1. Introduction 5
6 IBM VA for COBOL OO Programming
Chapter 2. OO Concepts
The unit of computing is the object. This is the atomic component, indivisible by
other computing constructs. The object is written and plugged together in larger
units, as atoms are grouped into molecules and thence to everything we see
around us.
There are many reasons why this might be more than a wild prediction by
someone with a vested interest. For the moment we can consider just two: the
engineering analogy and the client-server paradigm.
The engineering analogy says that if ever the production of software is going to
catch up with demand, it will need to adopt the engineering approach of
assembly of standardized parts. This is not a novel proposal but what is new is
the prospect of object technology fulfilling that role.
IBM is involved in such object-oriented activities as its internal group, the OTC
(Object Technology Council). OTC promotes the use of OO throughout IBM′ s
development work. An example of its success is the 500,000 lines of MVS
products already produced using an object-oriented approach. Much of the
visual part of VisualGen was written in Smalltalk and there are many other
examples.
Externally too, IBM is fully involved, in particular with the Object Management
Group (OMG). This consists of over 400 companies striving to promote the
standardized approach required to deliver the greatest benefits of
object-oriented technology.
There have always been problems when new technology has been employed to
improve the performance of AD.
Chapter 2. OO Concepts 9
Apart from OO, what is there? One approach is outsourcing. Widely tipped as a
growth area in the late 80s, actual experience has demonstrated that outsourcing
moves the problem around rather than solves it.
Everyone agrees that greater re-use of code would mean both faster and more
productive development as well as the delivery of more reliable code. The
difficulty has been in facilitating re-use.
Objects are clearly defined, indivisible combinations of function and data. This
suggests that it should prove possible to select objects which have been written
earlier. AT&T claims that only 20% of their code now has to be newly written.
The rest is reused as a result of using an object-oriented approach. The concept
of inheritance further facilitates this suitability for re-use by making simple, local,
adjustments to an object possible without copying it.
Users can also relate to descriptions based on objects in a way that they might
not with DFDs (Data Flow Diagrams) or ERs (Entity-Relationship) diagrams as
shown in Figure 6. like. This should improve the communications between
Information Technology (IT) and the user departments.
Client-server systems might not have exploded in the way predicted but it is
plausible to assume that their use will increase. Their mode of operation can be
characterized as one unit of processing sending a request to another unit which
in turn responds. This picture matches the way objects send messages to each
other. This means that the object-oriented approach fits the natural topology of
the system architecture.
If object-oriented is such a good idea, why has it not been thought of earlier? It
was thought of earlier but there were physical inhibitors which hindered its
adoption.
One inhibitor was that the first object-oriented languages required the learning of
a completely new system. This inhibitor began to disappear, at least for C
programmers, with the introduction of C++.
Another inhibitor was that all technology was either UNIX- or PC-based. This
ruled out major commercial systems being created to use object-oriented
technology. Finally, since one of the attractions of object-oriented technology is
its encouragement of re-use, in particular via the supply of pre-written objects,
time is needed to build up a library of these objects. Who wants to invest in
producing pre-written objects for sale?
These inhibitors however have begun to diminish in the last few years.
Object-oriented programming has moved out of the academic laboratory into the
commercial mainstream.
Chapter 2. OO Concepts 11
2.5 OO Terminology
This section explains the basic terms involved with object-oriented programming.
Fortunately, you can say the basics are as easy as PIE (Polymorphism,
Inheritance, and Encapsulation) as shown in Figure 7. It is important to first
understand objects themselves.
Figure 7. OO Terminology
Objects consist of two sets of components: their data and the functions that work
on that data. These functions (called ″methods″) are the only way of accessing
that data, that is, creating, reading, writing. This is called ″encapsulation.″ It is
one of the mechanisms which give object-oriented its robustness since it is a
strong encourager of data integrity. Encapsulation is illustrated in Figure 9.
Chapter 2. OO Concepts 13
Figure 9. Encapsulation
Often objects are similar in most respects without being identical. Perhaps
object B has some more or some less data defined than object A, or one or two
extra or fewer methods.
Chapter 2. OO Concepts 15
Figure 11. Polymorphism
One object communicates with another via a message as shown in Figure 13.
For example, the wine application has objects ″wine-type″ and ″grape-type″. To
check if we can drink a certain bottle with a piece of food, we send a message to
our ″wine-bottle″ object specifying the method ″wine-bottle OK with food ?″
together with a piece of data ″roast beef″. The wine-bottle object′s method then
sends a message to its ″wine-type″ object saying, say ″wine OK with food ?″ and
the same data ″roast beef″. The ″wine-type″ object then sends a message to the
″grape-type″ object saying ″grape-type OK with food ?″ and ″roast beef″. Finally,
the ″grape-type″ object checks its list of acceptable foods and sends a message
back, this time just with some data.
Chapter 2. OO Concepts 17
Figure 13. Messages
This example is useful for distinguishing classes from objects. There is just the
one class ″grape-type″ but there are many ″grape-type″ objects: one for
Cabernet Sauvignon, one for Merlot, one for Zinfandel, one for Chardonnay, and
so on.
So, the basic terms used to discuss object-oriented are summarized in Figure 14.
It really is as easy as PIE!
2.6 OO Review
Figure 15 reviews the claims of object-oriented programming and how the
various components of object-oriented contribute.
Re-use comes from the basic object identity and the ability to obtain slight
modifications without copying by ″inheritance″.
Chapter 2. OO Concepts 19
Figure 15. How OO Scores
2.7 OO History
OO was first discussed by a group of people working on the SIMULA language in
the late 1960s. Xerox PARC researchers developed Smalltalk-80 in the late
1970s. Bjarne Stroustrup developed C++ for Bell Labs in 1981.
Taligent was founded as a joint venture between IBM and Apple (later an
investment made by Hewlett-Packard). This development is illustrated in Figure
16.
The reasons for the strange name is that the COBOL standards group is known
as X3J4. The corresponding ISO group, the international COBOL standards
committee, is called ISO/IED JTC1 SC22/WG4, or WG4. WG4 has subcontracted
the work of developing the new COBOL standard to X3J4. The relationships are
shown in Figure 17.
Chapter 2. OO Concepts 21
Figure 17. OO COBOL Standards
Chapter 2. OO Concepts 23
24 IBM VA for COBOL OO Programming
Chapter 3. Old COBOL Approach
3.1 OO Image
Many people, even those involved with OO, think of it as a workstation-based
technology. The image refers not to the actual platform but to the small scale
nature of its operation.
However this is not so. One of the best OO references is the Brooklyn Union
Gas Company that rewrote their Customer Information System (CIS) between
1987 and 1990 in an object-oriented way as referred to in Figure 19. This CIS
manages a $1 billion revenue stream, uses a 100 gigabyte database, has over
400 screens with 850 users, and processes 350,000 transactions per day at an
average rate of ten transactions per second.
Thus the program is the object, and the data is accessed only by routines in this
program.
COBOL can provide inheritance too as shown in Figure 21. We define a second
program which contains the extra routines not in the original program. Our
second program tests to see if it is being asked to perform one of its extra
methods. If so, it does. If not it calls the original program passing the
parameters it itself received.
This second program needs to contain nothing about how the original program
works, or even what it can and can′t do. If an invalid request has been made,
the first program handles it just as if it had been sent the request directly, that
is, it is transparent to the second program.
When the first program is invoked, its routine is the one that runs.
There is no explicit object and class definition. It is implicit if one follows the
installation conventions but it is not possible, for example, to list what classes
are defined. Similarly the methods are simply routines that are in the program.
They would be difficult to locate and their parameters might have to be
artificially manipulated for them to work.
It is not possible to associate data with a particular method and have it be used
by other methods in the same program.
Data must be copied everywhere. For example, the data definitions for a
wine-bottle must be in both the wine bottle program and the inherited claret
program.
Because we′re using an imitation object approach, it is not possible for objects
to have a two way conversation with objects written in another language.
4.1 Requirements
Figure 24 illustrates the requirements for the new COBOL approach. We need to
add facilities to either the language or the environment to address the points in
Figure 24. These can be summarized as allowing explicit definitions, messaging,
keeping the one copy of object data, and adopting a defined, standardized
approach.
Just as in old COBOL we can refer to data of different ″types,″ such as decimal,
binary, alphanumeric, and so on, in OO COBOL we have a new data type, the
Object Reference. This means that we can keep it in one place, and point to it
from everywhere else. But we still can access its data only with its methods.
This has the additional benefit that we can work on the object as an object, for
example to compare it with another.
In the sequence above we have used a ″client″ program. But this program itself
could be an object, initiated by the system itself on start-up.
4.4 Recursion
One powerful and required new facility is the ability of the objects to send
messages to themselves or even allowing a method to call itself. This technique
is called recursion as shown in Figure 27. The traditional example quoted in
computing is the calculation of factorials.
Another example is the bank account object sending a ″Withdraw $100″ message
and sending itself a message ″Give balance″ first to check that there is indeed
enough money in the account to allow the $100 to be withdrawn.
A new statement allows the definition of a class, another for a method, another
for the method-specific data, and several new statements allow reference to
other classes. A new statement allows programs to send messages to objects
(the ″invoke″ verb).
One problem has been incompatibility, not only between one language and
another but between the same language provided by different suppliers. In
particular, an object created using C++ from supplier B is not necessarily
compatible with a C++ object from supplier M.
SOM provides:
• A mechanism for defining classes and class libraries
• Object management services.
A rough analogy might be CICS. The programmer is still responsible for writing
the program but after that CICS handles the details, such as the registration of
the program, its invocation when required, its memory management. In addition
CICS does not care whether the program is PL/I, COBOL, or C.
With SOM, it is possible to use compilers for different languages from different
suppliers. It is not necessary to recompile programs when access methods
change (assuming that the change does not directly affect that program).
Software companies can now offer Class Libraries, secure in the knowledge that
their code cannot be copied, but still allow the user ability to use and inherit
from what they have provided.
Implementation means what the methods actually do. Interface means the
names of the methods, how many parameters they take, and what data types
they are, not what they do.
Platform availability: SOM was originally available on the OS/2 platform only.
But it is now available on AIX, Microsoft Windows, and MVS as shown in Figure
33. Classes defined to SOM on one platform can be readily ported to any of the
other platforms.
There is very little of SOM of which the COBOL programmer has to be aware as
shown in Figure 35. The COBOL compiler interacts with SOM in an automatic
manner so that as a by-product of compilation, all SOM′s required information is
stored in SOM′s Interface Repository, its database.
SOM therefore provides for COBOL a standard approach, one which ensures
maximum portability, flexibility, and interoperability. It moves OO programming
from the isolated, single-system approach towards the multi-system,
multi-connected object world of the future as shown in Figure 36.
Because of COBOL′s ″Direct-to-SOM″ facility, COBOL shops can now start the
journey, secure in the thought that they will not have to change before
completion.
As shown in Figure 38, the three leading OO languages are COBOL, C++, and
Smalltalk. Many alternative object-oriented implementation decisions have been
made.
C++ and Smalltalk also maintain relative and absolute popularity based on the
number of skilled practitioners.
One feature which might be of value would be what are called persistent objects.
Without this, objects exist from when they are invoked until the end of the
invoking program. As the name implies, ″persistent″ objects can continue
existing beyond the life of the invoking program, thus allowing other programs
and objects to communicate with them.
Associated with that is the need for something called ″garbage collection.″ This
is a procedure to clean up any unwanted objects, that is, nonpersistent objects
which have not been deleted. Without this clean-up, storage would gradually
become taken by all the unused objects.
One other refinement would be to specify different categories of use for methods.
Currently, anyone can use any method. It might be useful in some circumstances
to restrict the use of a method to the object itself.
5.1 Evolution
Implementation offers four logical possibilities: a non-COBOL/370 customer can
use OO COBOL on a mainframe or on a workstation, and so can a COBOL/370
customer. This is illustrated in Figure 40.
Of these four options, the non-COBOL/370 customer should probably avoid the
mainframe OO initially because that involves two new concepts simultaneously
(OO and Language Environment (LE)). It would be better to work with OO on the
workstation and, as a separate exercise, move to LE on the host.
Either option, workstation OO or host OO, is viable for the COBOL/370 user. The
host option looks more attractive because there is less new setup. If a team
were to be set up to work with OO on the workstation they would probably
include a majority of mainframe-experienced people. This might introduce an
extra delay in the learning process.
It is rather like giving a person who manually typed and mailed letters a PC with
E-mail links. If that person uses the PC to type letters, prints them and mails
them, not a great deal of benefit has been gained.
There will also be explicit support for the infrastructure products such as DB2,
IMS, and CICS, but (from an OO point of view) that support does not yet exist.
So, even if an organization were to have all the skills and experience they would
still be forced to develop everything the hard way. See Figure 42.
Education will vary from country to country, but should include some or all of the
following:
• SOM
• OO Analysis and Design
• COBOL language
Chapter 5. Implementation 49
Figure 43. Internal I B M Resources
The IBM OO Technology Center (OTC) formed in 1992 supports the move of
IBM′s software development groups towards the use of object technology. Its
tasks include:
• Promotion of OO technology benefits
• Building of expertise
• Development of a document library
• Consulting services
• Assistance to software groups in application assessment and deployment
plan preparation
Finally, there is the object-oriented part of the IBM Consulting Services group in
Boulder, Colorado.
5.4 Timescales
It is not possible to quote from COBOL experience since OO technology is so
new. However, the Smalltalk example in Figure 44 shows that the elapsed time
for building an effective and experienced OO team is years, not months, and that
acquiring the language skills is not a major barrier.
5.5 Conclusion
IBM′s OO COBOL is a technology breakthrough. Bringing together two of the
major AD technologies − the one vastly widespread and familiar, the other vastly
promising − is itself of major significance. But to do this on both workstation and
mainframe platforms, and to do so on the back of CORBA compliant SOM marks
a massive milestone in the history of AD as indicated in Figure 45.
Chapter 5. Implementation 51
Figure 45. Breakthrough
With mainframe and COBOL support, IBM customers can now take advantage of
it object-oriented programming. This will take time. But starting now means
customers can develop their competence without the pressures of undue haste.
IBM has much to offer in this process that no one else can.
6.1 Purpose
After completing this section, the reader should be able to write simple
object-oriented programs using the new COBOL family. They may be simple
ones, but all the new syntax is explained with examples and explanations.
6.2 Format
The sequence of topics is:
Class definition
Method definition
Client definition
Subclasses
Metaclasses
SOM use
The idea is to build up logically, starting with classes and methods, then the
client programs using the methods to access the classes, then the refinement of
subclasses, before talking about metaclasses. At the end we′ll explain SOM and
where to find out more information.
Customers order by the case of 12, which can be mixed and incomplete. In
dealing with customers you might want to check an old case order or to create a
new case order.
When checking an old case, the customer gives the case number and then you
check to see if each bottle is in stock. You produce a list of any that are not in
stock. We do this for as many cases as we like and when we stop we want to
know how many cases we have checked.
When creating a new case we add bottles, or delete any added by mistake.
Once complete, we are given a case number and the cost.
We build this system in three examples. Examples one and two implement part
of the final design requirement. The third example implements the overall design
requirement.
Typically, and certainly for the examples described in this manual, there is one
client program and several class programs. In this context, the client code is a
procedural piece of code which references the class programs as its logical flow
demands, just as a conventional program references called programs. These
programs can be developed using the Visual Development Environment, but for
simplicity, the command-line is used.
While the class programs can be in any order, the client program must always
be named first, since this determines the executable program. The COB2
command compiles all the programs and then, if the compilations have been
successful, links all the programs into the one file.
Chapter 6. O v e r v i e w 57
58 IBM VA for COBOL OO Programming
Chapter 7. Classes
The first part of this book provided an initial understanding of OO concepts. Just
as a reminder, though, objects in OO are combinations of data and the functions
that work on that data (called ″methods″). The data is only accessible via those
methods.
The business problem task is to define two classes : Winecase and Userint.
The wine case has have four items of data with self-explanatory names and six
methods whose purpose is as follows.
1: somDefaultInit (override) This method is invoked automatically whenever any
object is created or ″instantiated″. We take advantage
of that to initialize our data items here.
2: AddBottle Adds a bottle to our case, setting a flag to indicate
success or failure.
3: RemoveBottle Removes a bottle from our case, setting a flag to
indicate success or failure.
4: CalculateCost Computes the cost of our case.
5: GetCaseNumber Provides the number of the case, established by the
first method.
6: DescribeCase Writes the details of the case to a file, referenced by
variable “casedata.”
Our other class, UserInt, has just two items of data: user-action and user-bottle.
At any one time, the flow of data from the user to the application (by definition,
via this user interface class) only contains two items of data: what the user
wants to do (the action, for example add a bottle or end the application) and, for
the add and delete actions, the bottle details.
At the beginning and at the end of the definition, you have a class name instead
of a program name. You also mention the classname in the Environment
Division. This connects the class name in COBOL to the name in the outside
world using SOM. An entry (File Control) in the Environment Division connects
the file as COBOL refers to it in the program and the file name as the outside
world sees it. The Data Division contains the definitions of all the data items that
objects derived from this class use. The Procedure Division contains all the
Chapter 7. Classes 61
method definitions, as we′ll see in the next chapter. Case matters only within
quotes. The period in Repository section is only at the end.
The words in italics are the words under the user′s control. Other words, such
as “Class-ID,” are part of COBOL.
• Class-ID paragraph.
In the Class-ID statement, the classname must be the same as the
subsequent other two references, in the Repository section and in the End
Class statement. Case is not important nor does the name used in this
definition have to be the same as references in other definitions or client
programs. However, to avoid confusion, be consistent in naming and in case
usage everywhere.
The classname after the ″inherits″ is the class from which this class directly
inherits. Every class eventually inherits from SOMObject but only the
immediate ancestor is required.
• Repository paragraph
This is our link to the outside world. Our class definitions held in the SOM
Interface Directory where they are referenced by other class definitions and
by client programs (in both cases, possibly by non-COBOL code), both at
compile and at runtime.
The first name must match our references within our program while the
second name, inside quotes, determines what is stored or what is being
referenced in the SOM Interface Repository.
While case is not important almost everywhere else, it is important within the
quotes on the Class-ID statement. The Repository Section consists of a number
of ″Class X is ′ Y′ ″ statements. Only the last one requires a period (or full stop).
Chapter 7. Classes 63
64 IBM VA for COBOL OO Programming
Chapter 8. Methods
Our business example has two classes with nine methods between them as
shown in Tables 3 and 4.
The methods are defined in the Procedure Definition of the Class definition.
Like a class definition, at the beginning and at the end of the definition, there is
the method name instead of the program name.
The words in italics are the words under user′s control. The other words, such
as Method-ID, are part of COBOL.
• Method-ID paragraph.
In the Method-ID statement, the methodname must be the same as in the
End Method statement. Case is not important.
An optional keyword Override is specified if the method name is the same as
a method defined further up the inheritance chain. We shall discuss this
further in the sub-class topic.
• Environment Division
There is no a configuration section. The File Section is here just as in a
normal program.
• Data Division
The difference between Local-Storage and Working-Storage is that data in
working storage is always accessed in the last-used state when the method
is invoked. Conversely, data in local-storage is refreshed every time the
method is called.
Chapter 8. Methods 67
68 IBM VA for COBOL OO Programming
Chapter 9. Client
Between the creation and freeing of the objects, there is a simple loop asking
the user to add or delete bottles, followed by a short calculation and a message
issued to the user.
The letters (C) and (U) indicate object references to the wineCase and
Userinterface objects, respectively.
The words in italics are the words under the user ′s control. The other words,
such as Program-ID, are part of COBOL.
Object References can be at any level, other than 66 and 88, and as part of a
group. (If the object reference is itself the group item, it is the item at the lowest
part of the group which represents the actual handles.)
The only way an object reference data item can be used in the procedure
division is with the verbs shown here.
Chapter 9. Client 71
Creating an object is also known as creating an instance of a class. Do this with
the Invoke statement. We invoke the method somNew against the classname
asking the system to return us a handle in the specified handlename. Yet we
have already tied the classname and the handlename together in the Object
Reference statement in the Data Division. Does this give the system
unnecessary information?
The handlename might have been specified on a universal Object Reference and
so we must specify the sort of object we want.
To use a method, we again use Invoke, specifying both our handlename and the
method name. Methodname is typically a literal, although it can be a variable.
In this case the handle must relate to a universal object, not a typed object.
If we are passing data to the method, we specify the data item name in the
Using clause. If we expect data back from the method, we specify that data item
in the returning clause.
Note: Returning is now available on the CALL statement too. These using and
returning data items must be defined on the corresponding Procedure Division
statement of the method being invoked.
We can also perform comparisons and settings. We can compare one handle
with another, or check if it has not been set. Similarly, we can set the handle to
another or to be as if it has not been set. Typically, universal object references
are used in these cases.
All our interactions reference a handle of the object with the exception of the
somNew method, issued against the classname. Until the object has been
created we cannot invoke any of its methods. Actually there is an object for
each class defined in our Interface Repository (not to be confused with objects
that we create from our class′s definition) and it is that object whose method
somNew we invoke.
This chapter contains examples of the code used in the first version of the
sample Wine program, illustrating class definition and object interaction. For
space reasons, the comment lines have been omitted. The simplicity of the code
should facilitate easy comprehension. Appendix A contains the full code listing.
Get-item.
Display ″Enter the item″
Accept Bottle from SYSIN
Move Bottle to User-Bottle.
Version 1
PROGRAM-ID. Wine.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS Case IS ″Winecase″
CLASS UserInterface IS ″UserInt″.
DATA DIVISION.
Working-Storage Section.
77 caseObj Usage Object Reference Case.
77 userObj Usage Object Reference UserInterface.
77 Case-number Pic 9(5).
77 total-cost Pic 9(7)V99.
77 action Pic X(10).
77 bottle Pic X(20).
77 flag Pic X.
PROCEDURE DIVISION.
Invoke UserInterface ″somNew″ RETURNING userObj
Invoke Case ″somNew″ RETURNING caseObj
Invoke userobj ″ReadInput″ Returning bottle action
Perform until action = ″End″
IF action(1:3) = ″Add″
Invoke caseObj ″AddBott″ Using bottle Returning flag
ELSE
Invoke caseObj ″DeleteBott″ Using bottle Returning flag
END-IF
Invoke userObj ″WriteMessage″ Using flag
Invoke userObj ″ReadInput″ Using bottle action
End-Perform
Invoke caseObj ″CalculateCost″ Returning total-cost
Invoke caseObj ″GetCaseNumber″ Returning case-number
Invoke userObj ″WriteOutput″ Using total-cost case-number
Invoke caseObj ″DescribeCase″
Invoke caseObj ″somFree″
Invoke userObj ″somFree″
STOP RUN.
END PROGRAM Wine.
A similar set of mismatches can be seen with data items. It would be possible
to take each class separately and define its methods repeatedly but this would
not maximize the reuse.
Then the subclasses only need the methods and data relevant to them. Thus
when we send a method get-length-of-trunk to the elephant, it deals with it.
However if we send describe-habitat to the elephant, the class passes it to the
animal class.
Table 8 (Page 1 of 2). Winecase Class with Data and Methods (Subclasses)
Winecase
Data (Case-number)
(Case-date)
Methods 1:
2:
3:
4:
5:
6:
7:
8:
Up to now we have been dealing with the latter type. We assumed that we only
want to define new cases. But in fact we want to be able to query existing
cases, to see what their cost is and to check whether the bottles specified are in
stock. Doing this requires two new methods: ReadCase and CheckBott. These
are not new cases so they are defined in the OldCase class.
In the Class-ID statement naming the subclass, the class from which it is directly
inheriting, generically referred to as a Superclass, must be explicitly named.
Both these classes must be named in the Repository section and any classes
Methods in subclasses are defined in the same way as those in classes. Often,
though, they override ones with the same name in the superclass. In these
cases the word Override is added to the name.
We have already seen this when somDefaultInit was overridden. Every class
(except SOMObject) has a superclass in IBM OO COBOL. The inheritance chain
always leads to SOMObject. Thus, in any class we can override, at the very
least, the 22 (at the current count) methods defined in SOMObject, one of which
is this ″somDefaultInit.″
Everything else about the definition is identical to the class definition. There are
however some coding aspects of the Procedure Division which are particularly
relevant in subclass methods.
The first occurs when we want to use the original superclass method. In these
cases the SUPER term is used.
The system interprets the word SUPER as meaning “look in the parent class for
this method” (“and then in the grandparent” and so on). SUPER should only be
specified in method code, not in client code.
• In Oldcase subclass,
Method ″CheckBott″
....
Invoke SELF ″GetInstanceData″ Returning Case-details
....
In the superclass we write two methods, one to read all the data and one to
write it all. From the subclass we issue the Invoke SELF statement specifying
the appropriate method name.
“SELF” is shorthand for asking the system to invoke the specified method
against the object from which it is being issued (and then against the object′ s
parent, and so on). SELF, like SUPER, should only be specified in method code,
not in client code.
The difference between a subclass invoking this method and a class doing so is
that the subclass does not need to instantiate the superclass; it is the object. By
contrast, another class invoking GetInstanceData against the winecase class
would first have to obtain an actual object representing the actual case.
With new constructs of subclasses, method overrides, and using SUPER and
SELF, we can now construct a second version. Appendix B contains the full code
listing.
12.1 Winecase
IDENTIFICATION DIVISION.
METHOD-ID. ″somDefaultInit″ OVERRIDE.
Same as Version 1
END METHOD ″somDefaultInit″.
IDENTIFICATION DIVISION.
METHOD-ID. ″GetInstanceData″.
DATA DIVISION.
Linkage Section.
01 out-case.
05 out-case-number Pic 9(5).
05 out-case-date Pic X(8).
05 out-case-count Pic 99.
05 out-case-contents.
10 out-case-entry occurs 12 times.
15 out-case-bottle Pic X(20).
PROCEDURE DIVISION Returning out-case.
Move case-number to out-case-number
Move case-date to out-case-date
Move case-count to out-case-count
Move case-contents to out-case-contents
Exit method.
END METHOD ″GetInstanceData″.
IDENTIFICATION DIVISION.
METHOD-ID. ″AddBott″.
Same as Version 1
END METHOD ″AddBott″.
IDENTIFICATION DIVISION.
METHOD-ID. ″CalculateCost″.
Same as Version 1
END METHOD ″CalculateCost″.
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCaseNumber″.
Same as version 1
END METHOD ″GetCaseNumber″.
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeCase″.
Same as Version 1
END METHOD ″DescribeCase″.
END CLASS Winecase.
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadRequest″.
DATA DIVISION.
Linkage Section.
01 Request Pic X(6).
PROCEDURE DIVISION Returning Request.
Display ″Enter the request: new, status″
Accept request from SYSIN
Move Function Upper-case(request) to Request
Exit Method.
END METHOD ″ReadRequest″.
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadInput1″.
Same as ″ReadInput″ in Version 1
END METHOD ″ReadInput1″.
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteMessage″.
Same as version 1
END METHOD ″WriteMessage″.
IDENTIFICATION DIVISION.
METHOD-ID. ″Writeoutput″.
Same as version 1
END METHOD ″Writeoutput″.
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteStatus″.
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 Value 99.
Linkage Section.
01 Out-table.
05 Out-Entry occurs 12 times.
10 Out-Bottle Pic X(20).
01 Out-count Pic 99.
PROCEDURE DIVISION Using Out-table Out-count.
IF out-count > 0
Perform varying sub from 1 by 1
until sub > out-count
Display ″Out of stock ″ Out-Bottle(sub)
End-Perform
END-IF
Exit Method.
END METHOD ″WriteStatus″.
END CLASS UserInterface.
Version 2
PROGRAM-ID. ″Wine″.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS NewCase IS ″NewCase″
CLASS OldCase IS ″OldCase″
CLASS UserInterface IS ″UserInt″.
DATA DIVISION.
Working-Storage Section.
77 univObj Usage Object Reference.
77 userObj Usage Object Reference UserInterface.
77 Case-number Pic 9(5).
77 total-cost Pic 9(7)V99.
77 out-count Pic 9(2).
77 request Pic X(6).
77 action Pic X(10).
77 bottle Pic X(20).
77 flag Pic X.
01 Case-Contents.
05 Case-Entry occurs 12 times.
10 Case-Bottle Pic X(20).
PROCEDURE DIVISION.
Invoke UserInterface ″somNew″ RETURNING userObj
Invoke userobj ″ReadRequest″ Returning request.
IF request = ″STATUS″
Perform CheckOldCase
ELSE
Perform CreateNewCase
END-IF.
Invoke userobj ″somFree″
STOP RUN.
CreateNewCase.
Invoke NewCase ″somNew″ Returning univobj
Up until now we have only considered activities with individual objects, for
example updating data for a specific case of wine, that is, one case equals one
object.
Suppose we want to do something with all the objects of a particular class? For
example, we might want to count how many cases we have referenced or know
the maximum cost of our cases (assuming that cost was something we stored).
We might want to list all the dates that our cases were ordered.
It might be possible to write the routine in a client program but we would have to
repeat the code in every client program.
Suppose when we create an object we want all its data to be loaded from a file.
If it were the same data for each object in our class, there is no problem. We can
override the somDefaultInit method in our class definition and put the code
there.
But in practice that data would be dependent on some key value, such as a
personnel number, an account number or a case reference number. We cannot
pass that to somDefaultInit because it is not expecting a parameter.
Again, we could write a method which we explicitly invoke after creating the
object (this is what we did in Example 2), but if we wanted to be sure this
happened (for example, to write an audit record) must rely on the client program
coder.
A guaranteed action might also be required on freeing up the object. This might
or might not be possible by overriding somUninit.
13.2 Definition
The use of metaclasses answers the needs explained in the last section. The
concept can be thought of as follows:
• Objects can represent anything, such as people, accounts, orders, cases of
wine
• All objects have classes which define them
On the right side of Table 13 there is a metaclass for the ClaretBottle Class
called MetaClaret. This inherits from a chain of classes culminating in one
called SOMClass.
It might inherit directly from SOMClass, or there might be 100 classes inbetween.
There is no need for there to be a metaclass for WineBottle or Container. Even
if there were, there would be no need for those classes to be in the MetaClaret
to SOMClass chain.
On the left-hand side any methods higher up the chain from ClaretBottle such as
ListPrice or StateSupplier can be used on ClaretBottle and we can add methods
or data to ClaretBottle which do not apply higher up the chain. For example, we
might want for ClaretBottle to have a method EstimateValue and a new data
value called Value.
This is called a ″constructor″ method. There are ″destructor″ methods too which
might, for example, reduce the value of COUNT by one.
13.4 Definition
The structure of a metaclass definition is like a class definition:
• ID Division.
Class-ID. Metaname Inherits SOMClass.
......
• Environment Division.
Repository.
Class Metaname is ″ Metaname ″
Class SOMClass is ″SOMClass″.
......
• Data Division.
Working-Storage Section.
(No Local Storage, NO Linkage)
(No Value clauses)
• Procedure Division.
... (discussed later)
• End Class Metaname
Like any other class definition, a metaclass has the usual four divisions:
Identification
Environment
Data
Procedure
Whatever name is put where SOMClass, is must match the first name on the
corresponding Class statement in the Repository section. Case is ignored. This
is also true for the name of the metaclass itself, which must match the name
specified on the End-Class statement after the procedure division.
Convention dictates that the actual names as defined in the SOM Repository be
used as well.
In the Procedure Division, the division statement itself specifies that the object
defined is returned. The executable statement Invoke must be coded specifying
SELF (case is not significant) as the class and somNew as the method.
Class programs
• ID Division.
Class-ID. Classname INHERITS ... METACLASS Metaname .
• Repository.
Class Metaname is ″ Metaname ″
Class Classname is ″ Classname ″
Client programs
• Invoking Constructor Methods
01 xyzObj USAGE OBJECT REFERENCE.
.......
Invoke Classname ″CreateObj″ Using ... Returning xyzObj
• Invoking Other Methods
01 pqrObj USAGE OBJECT REFERENCE METACLASS Metaname .
.......
Invoke xyzObj ″somGetClass″ Returning pqrObj
Invoke pqrObj ″OtherMethod″ Using ... Returning ...
This is the third and final version of our example. This example illustrates the
use of metaclasses. Appendix C contains the full code listing.
IDENTIFICATION DIVISION
CLASS-ID. MetaOldCase Inherits SOMClass.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS MetaOldCase IS ″MetaOldCase″
CLASS OldCase IS ″OldCase″
CLASS SOMClass IS ″SOMClass″.
DATA DIVISION.
Working-Storage Section.
01 status-count Pic 99.
PROCEDURE DIVISION.
*
*
*
IDENTIFICATION DIVISION.
METHOD-ID. somDefaultInit OVERRIDE.
PROCEDURE DIVISION.
Move 0 to status-count.
Exit Method.
END METHOD somDefaultInit.
IDENTIFICATION DIVISION.
METHOD-ID. CountOldCase.
DATA DIVISION.
Linkage Section.
01 out-count Pic 9(2).
PROCEDURE DIVISION Returning out-count
Move status-count to out-count.
Exit method.
END METHOD CountOldCase.
END CLASS MetaOldCase.
IDENTIFICATION DIVISION.
CLASS-ID. OldCase Inherits Winecase MetaClass MetaOldCase
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS MetaOldCase IS ″MetaOldCase″
CLASS OldCase IS ″OldCase″
CLASS Winecase IS ″Winecase″.
DATA DIVISION.
PROCEDURE DIVISION.
*
*
*
PROGRAM-ID. ″Wine″.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS NewCase IS ″NewCase″
CLASS OldCase IS ″OldCase″
CLASS UserInterface IS ″UserInt″.
DATA DIVISION.
Working-Storage Section.
77 univObj Usage Object Reference.
77 metaObj Usage Object Reference MetaClass OldCase.
77 userObj Usage Object Reference UserInterface.
77 Case-number Pic 9(5).
77 total-cost Pic 9(7)V99.
77 out-count Pic 9(2).
77 request Pic X(6).
77 action Pic X(10).
77 bottle Pic X(20).
77 flag Pic X.
01 Case-Contents.
05 Case-Entry occurs 12 times.
10 Case-Bottle Pic X(20).
PROCEDURE DIVISION.
Invoke UserInterface ″somNew″ RETURNING userObj
Invoke userobj ″ReadRequest″ Returning request.
IF request = ″STATUS″
Perform CheckOldCase
ELSE
Perform CreateNewCase
END-IF.
Invoke userobj ″somFree″
STOP RUN.
CreateNewCase.
Invoke NewCase ″somNew″ Returning univobj
Invoke userobj ″ReadInput1″ Returning bottle action
Perform until action = ″End″
IF action(1:3) = ″Add″
Invoke univObj ″AddBott″ Using bottle Returning flag
ELSE
Invoke univObj ″RemoveBott″ Using bottle Returning flag
END-IF
Invoke userObj ″WriteMessage″ Using flag
Invoke userObj ″ReadInput1″ Returning bottle action
End-Perform
Rather than duplicate material provided elsewhere, for example in the ″ Getting
Started ″ manuals listed in the bibliography at the beginning, the content is
designed to be complementary by providing an illustrative example.
Commentary brings out more clearly the point of the illustration.
15.1 Background
Our customer is a distant uncle on our mother′s side. He has turned his hobby
into a business and operates a retailing establishment for wine. As his business
has grown, his manual methods of order entry and inventory control have proven
inadequate. At Mom′s urging and in a less-than-lucid moment after a quality
control check of his products, he has contracted us to build an application
system for the operation of his wine retailing business.
When checking an old order, the customer gives the case number and the order
is checked to see if each bottle is in stock. A list is produced of any out-of-stock
When creating a new order, the seller adds bottles, or deletes any that have
been added by mistake. Once the order is complete, an order number is
assigned, and its cost computed.
16.1 Methodology
The methodology employed for this example draws on other established
object-oriented analysis and design methodologies, such as use cases from Ivar
Jacobson and CRC cards from Kent Beck. Other popular methodologies exist
such as Booch, OMT by James Rumbaugh, and the Fusion method by the
Hewlett-Packard Corp. Our methodology does not purport to champion one
methodology over another. Such a treatise is beyond the scope of the task at
hand. An underlying reason for our approach spares us the burden of learning
the complex system of notation used by other methodologies. It also allows us to
proceed, in a rather direct fashion, with creating a solution in code. The reader
familiar with introductory object-oriented concepts should be comfortable with
the steps employed.
16.1.1 Analysis
To implement the sample application, we employ the following procedures in our
analysis and design:
• Use cases.
In developing our use cases, we place ourselves in the user′s position and draft
textual descriptions of his procedures. Use cases can become a hierarchy, in
which a high-level use case uses one or more lower-level use cases. Use cases
consist of a set of actors or external agents, the usages of the system by the
actors, and links between the actors and use cases. Obviously, some limit must
be employed by the analyst, and a determination of when to move on to the next
step must be made to avoid analysis paralysis. But, generally speaking, time
spent in this phase is time well spent and pays dividends later in the
development process.
• Object identification.
This step identifies the objects the actors used in the use cases.
After our use cases have been formulated, we can analyze them and extract the
nouns that were used in their text. We examine these nouns with an eye
towards making them objects. In this examination, some of them clearly sift out
as objects, while others appear trivial and useless as objects. The analyst
therefore faces a decision: is this item an object or is it an attribute of another
object? It has been said that one man′s object is another man′s attribute.
• Method determination.
16.1.2 Design
Constructing object interaction diagrams is the first step in the design process.
Then we move on to implementing the design in code.
Typically, we produce an object interaction diagram for each use case that we
are implementing. These diagrams provide system designers an understanding
of the message flow between objects and the sequence of events in the use
case. A message to an object evokes a response from it. Object interaction
diagrams are dynamic models of the application, while use cases are static.
At this point in the design effort, we have identified the objects, their attributes
and methods, and their relationships to each other in the business process. We
can then begin to implement our design in code. In doing so, we may generate
new insights into the business process we are implementing and identify some
shortcomings in our design.
Basic Use Case -- A New Order is Placed: When the customer places a new
order for bottles of wine, the salesperson notes the bottles the customer has
selected on the order, assigns a unique number and the current date to the
order, and then adds the bottles of wine the customer has selected. The order is
a list of bottles selected. If the customer changes his mind about a bottle that
has been selected, the salesperson removes it from the order. As the
Objects Used in the WineStore: After the use case has been drafted, we
examine it to determine what objects are used in the business process.
We first list the nouns in the use case. We omit pronouns such as its and he/she
since, in actual usage, these are merely tags or synonyms for previously used
nouns. From the basic use case we have:
• Customer
• Order
• Bottle(s)
• Wine
• Salesperson
• Number (order number)
• Date (current date)
• Selections
• Mind
• Type
• Cost.
″Salesperson″ is an actor of our application, and the primary user of the system.
We do not consider him an object. However, we can make our interface with
him an object to isolate the business logic from the presentation logic in our
application.
″Wine″ is the substance in the ″bottles″ that we sell. It occurs in ″types,″ that is,
a ″bottle″ contains a certain ″type″ of ″wine.″ Bottles are the items placed in a
″container″ ordered by the customer. Bottle is a good candidate for an object in
our application; wine and type are interchangable, and attributes of the bottle
object. Selection is a synonym for bottle as used in the context of this
application.
From this list, we identify actions that relate to our objects: bottle, order, and
user interface. The remainder we discard.
″Assigns (order) number″ indicates a need to set instance data for the order.
Generally, if we set instance data for an object, we require a method to get the
instance data in the process. Since orders are referenced by unique number,
we need a method for getting the unique number.
″Assigns date″ indicates a need for a method of setting the date attribute of the
order method. We create a set method for this attribute as well.
″Notes bottles″ is an action taken by the user of the system, and indicates a
need to hold data about the selections in the order.
″Adds bottles″ and ″removes bottles″ are other methods that we need for our
order object.
″Compute (cost)″ indicates a method must be written to calculate the cost of the
order. To compute the cost of the order, the bottle objects must be capable of
returning their cost. Hence, cost is an attribute of the bottle object.
For the user interface object, methods are needed to accept input from the
system user and to display system responses.
− Methods:
----------------------------------------------------------------
Class: WineOrder
----------------------------------------------------------------
Responsibilities: | Collaborators:
Add a bottle to the order | UserInterface
Remove a bottle from the | UserInterface
order |
Calculate the cost of order | WineBottle, UserInterface
Describe the contents of | WineBottle, UserInterface
an order |
Get the order number | UserInterface
Get the order date | UserInterface
Set the order number | UserInterface
Set the order date | UserInterface
Externalize the order | WineBottle
|
|
− WineBottle Class
− Methods:
----------------------------------------------------------------
Class: WineBottle
----------------------------------------------------------------
Responsibilities: | Collaborators:
Get the bottle cost | WineOrder
Get the wine type | WineOrder
Set the bottle cost | WineOrder
Set the wine type | WineOrder
|
|
• UserInterface Class
To isolate the business logic from the presentation logic, we can add an object
that interfaces with the user of the application. This proves to be a useful
strategy if we later decide to alter the user interface. The business logic can
remain unchanged when making modifications to the user interface.
− Attributes:
− Methods:
----------------------------------------------------------------
Class: UserInterface
----------------------------------------------------------------
Responsibilities: | Collaborators:
Accept a request from the |
system user: |
--Add a bottle to order | WineOrder, WineBottle
--Remove a bottle from | WineOrder, WineBottle
order |
Respond to the system user: |
--Display a status message | WineOrder
--Display the order cost | WineOrder, WineBottle
and the order number |
--Display the order | WineOrder, WineBottle
contents |
|
|
The model classes could interface with the view, thereby saving an iteration of
returning to the controller to interface with the view. However, this is contrary to
the MVC paradigm, in which the controller controls both the model and the view.
It may be necessary for model classes to communicate with each other, but they
should never cross the model boundary and communicate with the interface.
The corollary is also true: the interface should not invoke model classes
directly, but should work through the controller. Strictly adhering to this pattern
provides encapsulation of the view class; the underlying rationale is that different
views may be added depending on requirements, and that the model and
controller classes will not require changes.
Test the Client Program: Even if the client program compiled clean, it must be
tested.
The new statement, Repository, introduces the list of classes the program will
reference. Specifically, this program links the terms used subsequently to refer
to the classes, for example TheOrder and UserInterface, with the names as SOM
knows them, for example ″WineOrder″ and ″UserInt″.
SOM is case sensitive while COBOL is not. This means that in the CLASS
statements, case is important only for letters between the quote marks. For
example, the ″W″ and the ″O″ in ″WineOrder″ must be in uppercase while the
other letters must be in lower case. Elsewhere, case can be used in whatever
way the developer is most comfortable. Thus ″TheOrder″ could be ″theorder″,
″THEORDER″, or even ″ThEoRdEr″ if required.
The last CLASS statement is concluded with a full-stop or period. All others
must not end this way.
The Data Division has no Linkage Section or Local-Storage Section, thus leaving
only a Working-Storage Section. The first part appears as follows:
DATA DIVISION.
Working-Storage Section.
01 orderObj Usage Object Reference TheOrder.
01 userObj Usage Object Reference UserInterface.
In the executable part of the code, in the Procedure Division, objects are referred
to using these definitions. For example, objects from the class ″TheOrder″ are
referenced using the term ″orderObj″. This is called a handle. Similarly
″userObj″ is a handle for objects of the UserInterface class.
All the remaining definitions are only work items used briefly in various
operations.
77 Item-type Pic X(20).
77 Item-cost Pic 999V99.
77 total-cost Pic 9(7)V99.
77 action Pic X(10).
77 Today Pic X(21).
77 flag Pic X.
There are other parameters possible on the CLASS-ID statement, but the only
mandatory one is the immediate ancestor of the class being defined, in this case
SOMObject.
As with the client program Wine, it is necessary to list all classes referenced
directly. The class we are defining, WineOrder, does not absolutely have to be
mentioned here. It must be all upper-case, no matter how it has been typed in
the CLASS-ID statement earlier. This means that every other program that
refers to the class must use upper-case letters between the quote marks in their
CLASS statements.
The first name in such a CLASS statement (that is, one referring to the class
being defined) should match the class-id statement.
Each order requires a five digit number to identify it. The date the order was
taken is recorded in YY/MM/DD form.
The only item in Working-Storage for the whole object is referenced both from
outside the class and by different methods within the class.
PROCEDURE DIVISION.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS Bottle IS ″Bottle″ .
Two important attributes for the application are the type of wine and its cost.
PROCEDURE DIVISION.
Our uncle, fired with the enthusiasm of a first-time encounter with computers,
has been reading technical magazines. He is now showing clear symptoms of
″a little learning is a dangerous thing.″
He has come across the concept of IBM′s System Object Model (SOM), which
has impressed him. As a result he has stated that his system must exploit SOM
facilities. We explain that SOM offers great benefit, such as the ability to mix
objects written in different languages and the support to enhance individual
components of systems without requiring wholesale recompilations. We tell him
that using IBM′s VisualAge for COBOL for OS/2 means he is already able to take
advantage of the benefits.
Unfortunately he has been overdoing the quality control checks of his own
product line again and is quite adamant: ″Either that system uses some of these
SOM classes or vendor discounts become invalid.″
We introduce some extra error checking and convert some of our code to
upper-case.
----------------------------------------------------------------
Class: FileRW
----------------------------------------------------------------
Responsibilities: | Collaborators:
Externalize the order to | WineOrder
a file |
|
Figure 49. CRC Card for Wine Store Scenario Second Iteration
The process statement specifies compiler options. We set the pgmname option
to mixed. The default of upper would normally be adequate, but if SOM
programs are to be called, for example, somGetGlobalEnvironment as is used
later, the option must be set to mixed.
IDENTIFICATION DIVISION.
PROGRAM-ID. ″Wine″ .
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″
CLASS UserInterface IS ″UserInterface″ .
CLASS Bottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
There are two new references to Classes in the client program Wine. One is to a
new Class FileRW and the other to the WineBottle class. This latter class
existed before, but its references were confined to the ″Order″ object.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 orderObj USAGE OBJECT REFERENCE WineOrder.
01 userObj USAGE OBJECT REFERENCE UserInterface.
01 bottleObj USAGE OBJECT REFERENCE Bottle.
01 fileObj USAGE OBJECT REFERENCE FileRW.
The order is initialized this time by its two explicit Set methods as opposed to its
InitOrder method. This is required because SOM does not allow us to pass
attributes to during object initialization using somNew. Hence, we create the
object with somNew, and then use set methods for its attributes.
INVOKE orderObj ″SetOrderNumber″ USING ORDER-NUMBER.
INVOKE orderObj ″SetOrderDate″ USING ORDER-DATE.
The client program itself generates and initializes a Bottle object, before adding
it to the order. The RETURNING clause on the AddBottle invocation passes a
structure, not an elementary data item. This technique is used when multiple
data items must be returned, since RETURNING returns only a single item. We
are expecting back a flag indicating the success or failure of the operation and
the item count.
INVOKE Bottle ″somNew″ RETURNING bottleObj
INVOKE bottleObj ″SetType″ USING ITEM-TYPE
INVOKE bottleObj ″SetCost″ USING ITEM-COST
INVOKE orderObj ″AddBottle″ USING bottleObj
RETURNING WS-PARMS
If the add failed, the object just created is destroyed. The need for this is
obvious as it is not in the collection, and we can′t do anything with it. We should
clean up the objects we create.
IF WS-FLAG = ″1″
INVOKE bottleObj ″somFree″
END-IF
INVOKE userObj ″WriteMessage″ USING WS-FLAG
For delete processing, we retrieve the bottle type and cost, and then create a
bottle object with these attributes. The newly created bottle object is then
passed to the RemoveBottle method. Upon return, the bottle object is destroyed,
and the user informed of the success or failure of the operation. The need to
create an object like the one we are removing will become evident when we
review the bottle and order classes.
WHEN ″DEL″
userObj ″ReadType″
INVOKE RETURNING ITEM-TYPE
userObj ″ReadCost″
INVOKE RETURNING ITEM-COST
INVOKE
Bottle ″somNew″ RETURNING bottleObj
bottleObj ″SetType″ USING
INVOKE ITEM-TYPE
bottleObj ″SetCost″ USING
INVOKE ITEM-COST
orderObj ″RemoveBottle″ USING bottleObj
INVOKE
RETURNING
WS-PARMS
INVOKE bottleObj ″somFree″
INVOKE userObj ″WriteMessage″ USING WS-FLAG
WHEN OTHER
CONTINUE
END-EVALUATE
INVOKE userObj ″ReadAction″ RETURNING ACTION
END-PERFORM.
A check is made of the number of bottles in the order. We don′t want to perform
any operations on an empty collection.
IF ITEM-COUNT = 0
THEN GOBACK.
The order is written to a file using a new object from the Class FileRW, and its
method XternOrder.
INVOKE FileRW ″somNew″ RETURNING fileObj.
INVOKE fileObj ″XternOrder″ USING orderObj.
INVOKE fileObj ″somFree″ .
INVOKE userObj ″somFree″ .
INVOKE orderObj ″somFree″ .
GOBACK.
END PROGRAM ″Wine″ .
The following methods override the default methods supplied with SOM and
inherited from SOMObject.
somDefaultInit Initializes a WineOrder object.
somFree Frees bottles, collection, and order.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineBottle IS ″WineBottle″ .
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″
These two classes are supplied with SOM. A set is a type of collection. While
we could order our collection, that is not necessary in this instance, so a set is
used. The objects are maintained in the set in no particular order. somf_TSet is
one of the SOM collection classes.
As before, the Bottle object has two data attributes, type and cost.
The method somfIsEqual tests whether two bottle objects are equivalent, as
determined by whether their types and costs are the same.
PROCEDURE DIVISION.
IDENTIFICATION DIVISION.
METHOD-ID. ″somfIsEqual″ OVERRIDE.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 ITEMTYPE PIC X(20).
01 ITEMCOST PIC 999V99.
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
01 theBottle Usage Object Reference WineBottle.
01 theEqualFlag PIC X.
theBottle is the object compared to this instance, so its type and cost are
obtained and compared.
All four other methods, Get Cost, GetType, SetCost, and SetType are unchanged
from Version One.
END CLASS ″WineBottle″ .
The first step in our extension of the application is to revisit the use case step.
We first add to the original use case, and then create a new use case.
Extending the Original Use Case: It is possible that one or all of a customer′ s
selections may not be in stock at the time of the order. When this occurs, the
available bottles are added to the order, and the order is set aside to be
completed when the out of stock selections arrive in the store′s inventory.
A New Use Case - The Salesperson Checks Old Orders: When the salesperson
checks old or existing orders, he gets the order number from the customer or
the order list and retrieves the sales record for the order. The inventory status
of selections that were out of stock when the order was filled is verified. This
information is conveyed to the salesperson.
From the second use case, we observe that we need a mechanism for checking
old orders. We shall create an old order object. It will inherit the attributes and
methods of the original wine order class. It will also include methods for
checking the inventory status of bottles that were out of stock when the order
was taken and a method to retrieve old orders from an external file. We need
not retrieve the objects we externalized in the first iteration, so to accommodate
this new requirement, we must develop a method to read the orders and place
them into objects.
To instantiate an old order object after it is read from our external flat file, we
need a method to set all the instance data of the order. To write an image of the
object to the flat file, we also need a method to obtain all the instance data.
These methods need to be added to our order class. Since we want these
methods to be usable across both old and existing order classes, we add them
to the existing wineorder class.
In the first iteration, we created a bottle class. We would expect a bottle object
to be able to tell us if it is in or out of stock. Therefore, we shall add a
GetStockStatus method to our bottle class. The OldOrder class will invoke this
method when it checks on the status of the bottles in the order.
− Methods:
----------------------------------------------------------------
Class: WineOrder
----------------------------------------------------------------
Responsibilities: | Collaborators:
Add a bottle to the order | UserInterface
Remove a bottle from the | UserInterface
order |
Calculate the cost of order | WineBottle, UserInterface
Describe the contents of | WineBottle, UserInterface
an order |
Get the order number | UserInterface
Get the order date | UserInterface
Set the order number | UserInterface
Set the order date | UserInterface
Externalize the order | WineBottle
Set all the instance data | FileRW
for an order |
Get all the instance data | None
for an order |
Get the stock status of a | WineBottle
selection |
|
|
• OldOrder Object
− Attributes:
----------------------------------------------------------------
Class: OldOrder
----------------------------------------------------------------
Responsibilities: | Collaborators:
Add a bottle to the order | UserInterface
Remove a bottle from the | UserInterface
order |
Calculate the cost of order | WineBottle, UserInterface
Describe the contents of | WineBottle, UserInterface
an order |
Get the order number | UserInterface
Get the order date | UserInterface
Set the order number | UserInterface
Set the order date | UserInterface
Externalize the order | WineBottle
Set all the instance data | WineOrder, FileRW
for an order |
Get all the instance data | WineOrder
for an order |
Get the stock status of a | WineBottle
selection |
Check the stock status of a | WineBottle
selection |
Read the order data from the | FileRW
order file |
|
• WineBottle Object
− Attributes:
− Methods:
----------------------------------------------------------------
Class: WineBottle
----------------------------------------------------------------
Responsibilities: | Collaborators:
Get the bottle cost | WineOrder
Get the wine type | WineOrder
Set the bottle cost | WineOrder
Set the wine type | WineOrder
Get the stock status | WineOrder, OldOrder
|
• FileRW Object
− Attributes: (none)
− Methods:
− CRC card:
----------------------------------------------------------------
Class: FileRW
----------------------------------------------------------------
Responsibilities: | Collaborators:
Externalize the order to | WineOrder
a file |
Reads an order from the | OldOrder
file |
|
• UserInterface Object
To isolate the business logic from the presentation logic, we add an object that
interfaces with the user of the application.
− Attributes:
− CRC card:
----------------------------------------------------------------
Class: UserInterface
----------------------------------------------------------------
Responsibilities: | Collaborators:
Accept a request from the |
system user: |
--Add a bottle to order | WineOrder, WineBottle
--Remove a bottle from | WineOrder, WineBottle
order |
--List contents of order | WineOrder, WineBottle
--Locate order using | WineOrder
order number |
Respond to the system user: |
--Display a status message | WineOrder
--Display the order cost | WineOrder, WineBottle
and the order number |
--Display the order | WineOrder, WineBottle
contents |
|
Also, we extend our client program to use the new classes and methods, and
add the logic to handle the new commands.
We start by adding the new methods to our existing classes, then create the new
class, and finally, extend our client program.
Since we are using SOM collection classes we must include methods in the
order object to retrieve the environment variable, the iterator, and the collection
created during the initialization of the order object. When we instantiate the
oldorder object, an order object is also created, and the environment variable,
iterator, and collection are built.
The WineOrder Class: For this iteration, we add two methods, SetInstanceData
and GetInstanceData, to the WineOrder class. The purpose is to inflate objects
or retrieve their attributes in one single method invocation.
The SetInstanceData uses the AddBottle method contained in the class. The
method must pass through the table of ordered items. For each one, it creates a
WineBottle object, and then invokes the AddBottle method on itself to create the
collection of items in the order.
The GetInstanceData performs the same operation in reverse. That is, it collects
and builds a table of the items in the collection. It also invokes the
GetOrderNumber and GetOrderDate methods to obtains these attributes of the
order.
The UserInterface Class: The changes required to this class are easily
implemented. The ReadProcess method obtains the desired process from the
system user and is implemented like the ReadAction method coded earlier. The
WriteStatus method expects a table of out-of-stock items and passes through this
table displaying them to the user. ReadOrder is also easy to implement.
The FileRW Class: This class is extended by the addition of the XReadOrder
method, which performs the inverse of the XternOrder method. It reads the file
until a record for the requested order number is found, and returns a structure
containing the record to the invoker, oldorder. By allowing oldorder to inflate the
object, FileRW does not need the handle of the order object.
The Wine Client Program: Finally, we must modify the Wine client program that
drives our application process. This program must be extended to process the
new and status commands. For the new command, we put the existing code in a
paragraph and perform it.
For the status command we must draft additional logic. We invoke the
UserInterface object to get the order number to be checked; once that data is
These items are connected with the new interface. This offers the user an extra
option, checking the status.
01 OUT-ITEMS.
05 OUT-COUNT PIC S9(4).
05 OUT-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON OUT-COUNT
INDEXED BY OUT-INDEX.
10 OUT-TYPE PIC X(20).
10 OUT-COST PIC 999V99.
In this iteration the user can check an order′s status. This code also cleans up
and exits.
INVOKE userObj ″somFree″ .
GOBACK.
CHECK-OLD-ORDER.
INVOKE OldOrder ″somNew″ RETURNING oldOrderObj.
INVOKE userObj ″ReadOrder″ RETURNING ORDER-NUMBER.
INVOKE oldOrderObj ″CheckItems″ USING ORDER-NUMBER
RETURNING OUT-ITEMS.
We create an oldorder object and invoke the user interface object to get the
order number. Then we pass the order number to the CheckItems method of the
oldorder object, which returns a structure containing the out-of-stock items.
INVOKE userObj ″WriteStatus″ USING OUT-ITEMS.
INVOKE oldOrderObj ″somFree″ .
CHECK-EXIT.
EXIT.
We invoke the user interface object to display the list of out-of-stock items to the
user, and destroy the oldorder object created during the process.
CREATE-NEW-ORDER.
We take the code written in the client program in the second iteration and place
it in a paragraph, which is performed from the code processing the command.
MOVE FUNCTION CURRENT-DATE TO ORDER-DATE.
COMPUTE WS-RANDOM-VAL = FUNCTION RANDOM.
COMPUTE ORDER-NUMBER = WS-RANDOM-VAL * 10000.
This initializes the counter for the number of items ordered. Since it is possible
to loop through this section of code, an initialization is required to allow multiple
orders to be placed during one execution of the client program.
The Identification Division, the Data Division (not shown here), and the
Environment Divisions are the same as in Version Two.
PROCEDURE DIVISION.
1. GetEV
This method and the next two are added to allow the new method
Checkitems to work. Checkitems is not defined here but in a subclass
(OldOrder) so these three methods can be defined there too. However, by
placing them in the superclass, and other classes subsequently defined as
subclasses of this we can inherit these methods. Note the use of set verbs
instead of move. In actuality, we pass pointer values, not data. So, you
cannot just move an object reference, you have to set it.
IDENTIFICATION DIVISION.
METHOD-ID. ″GetEV″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
PROCEDURE DIVISION RETURNING LS-EV.
SET LS-EV TO WS-EV.
EXIT METHOD.
END METHOD ″GetEV″ .
2. GetList
See the comment for methods ″GetEV″ above.
IDENTIFICATION DIVISION.
METHOD-ID. ″GetList″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 LS-LIST USAGE OBJECT REFERENCE SOMCollection.
PROCEDURE DIVISION RETURNING LS-LIST.
SET LS-LIST TO WINEORDER-LIST.
EXIT METHOD.
END METHOD ″GetList″ .
For example, it was possible to invoke the method AddBottle against an object of
the WineOrder class. Therefore, it is possible to invoke it against an object of
this class, OldOrder without having to repeat the method′s definition.
process test pgmname(longmixed)
IDENTIFICATION DIVISION.
CLASS-ID. ″OldOrder″ INHERITS WineOrder.
The CLASS-ID statement specifies from which class this class directly inherits.
Previously the ancestor class was almost always SOMObject.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS OldOrder IS ″OldOrder″
CLASS WineOrder IS ″WineOrder″
CLASS WineBottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″ .
DATA DIVISION.
No data items are defined because all the attributes of this class have already
been defined in WineOrder. If, for example, a program wished to discover the
order number of an object of this class it would invoke the method
GetOrderNumber against the object and the method would return the value. For
a method defined in this class to find out the order-number, it too would issue
the GetOrderNumber method. Only this time, the object-handle would be
replaced by the keyword SELF. For example,
Invoke objhandle ″GetOrderNumber″ etc
becomes
Invoke SELF ″GetOrderNumber″ etc
The new inputs that the user can make are listed below.
PROCEDURE DIVISION.
1. ReadAction
This is the same as Version Two.
2. ReadType
This is the same as Version Two.
3. ReadCost
This is the same as Version Two.
4. WriteMessage
This is the same as Version Two.
5. WriteOutput
This is the same as Version Two.
6. WriteBottle
This is the same as Version Two.
7. ReadProcess
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadProcess″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
LINKAGE SECTION.
01 LS-PROCESS PIC X(10).
PROCEDURE DIVISION RETURNING LS-PROCESS.
MOVE LOW-VALUE TO WS-EDIT-FLAG.
PERFORM UNTIL WS-EDIT-FLAG NOT = LOW-VALUE
DISPLAY ″Enter process desired: new, status: ″
ACCEPT USER-ACTION FROM SYSIN
MOVE FUNCTION UPPER-CASE (USER-ACTION) TO USER-ACTION
MOVE USER-ACTION TO LS-PROCESS
EVALUATE USER-ACTION (1:3)
WHEN ″NEW″
MOVE HIGH-VALUE TO WS-EDIT-FLAG
WHEN ″STA″
MOVE HIGH-VALUE TO WS-EDIT-FLAG
WHEN OTHER
DISPLAY ″Requested process was ″ USER-ACTION
DISPLAY ″Wrong! Get it right this time!!!″
END-EVALUATE
END-PERFORM.
EXIT METHOD.
END METHOD ″ReadProcess″ .
8. ReadOrder
19.3.6.1 Conclusion
After the third iteration of our development, we more closely model the business
process of the wine store. As we probe further, we discover that our application
isn′t quite complete, and another iteration is required.
To accommodate the new requirement from the users, we must create another
use case.
The Salesperson Checks the Status of Old Orders: When the salesperson
checks the status of old orders in the system, he reviews the orders in the order
file. For orders that have unfilled selections, he checks the inventory for the
selected bottles. If they are present, he adds them to the order. During this
review, the salesperson also wants to know how many old orders are present in
the system.
This use case indicates the need for a metaclass with information about an
existing class. To accommodate this need, we create a MetaOldOrder object to
count the old orders, and create an old order object to be checked.
− Methods:
− CRC card:
----------------------------------------------------------------
Class: MetaOldOrder
----------------------------------------------------------------
Responsibilities: | Collaborators:
Create an old order | OldOrder
Count the number of old | OldOrder
orders |
|
|
We start by adding the new methods to our existing classes, then create the new
class, and finally, extend our client program.
Changing the Wine Client Program: The client program requires that we invoke
the metaclass′s CreateOldOrder method in lieu of OldOrder′s CheckItems
method when we want to check an order. On return from this invocation, we
need to check a flag that indicates whether the order could not be found. If the
order was not on the order file, the WriteLost method of UserInterface is invoked,
and the rest of the code in the client is bypassed. The original action prompt is
redisplayed to the system user. At the conclusion of the program, we invoke the
metaclass′s CountOldOrder method and pass the returned count field to the
WriteOutCount method of the UserInterface.
To avoid redundancy, only the changed parts of the program are presented
below.
process pgmname(longmixed) test
IDENTIFICATION DIVISION.
PROGRAM-ID. ″Wine″ .
.
.
.
WORKING-STORAGE SECTION.
.
.
.
This code specifies the handle for the metaclass. It has an object reference to
the class it has knowledge of.
.
.
.
01 STATUS-FLAG PIC X.
88 NO-STATUS-SELECTED VALUE LOW-VALUE.
88 STATUS-SELECTED VALUE HIGH-VALUE.
.
.
.
This flag controls whether or not we invoke the classes and methods associated
with displaying how many OldOrders were checked. It initializes to a low-value
and sets to a high-value if we enter the CHECK-OLD-ORDER paragraph.
.
.
.
01 OUT-ORDERS PIC S9(4) COMP.
01 META-PARMS.
05 univObj USAGE OBJECT REFERENCE.
05 LOST-FLAG PIC X.
05 OUT-ITEMS.
05 OUT-COUNT PIC S9(4).
10 OUT-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON OUT-COUNT
INDEXED BY OUT-INDEX.
15 OUT-TYPE PIC X(20).
15 OUT-COST PIC 999V99.
.
.
.
This code adds a field for the counter to indicate how many OldOrders were
checked and includes a parameter structure for the metaclass to return to us.
The metaclass returns a generic object reference, as well as the substructure of
out-of-stock items which existed as a ″01″ level in the previous iteration.
PROCEDURE DIVISION.
MOVE LOW-VALUES TO STATUS-FLAG.
.
.
.
This code turns on the flag to indicate an OldOrder has been checked.
IF STATUS-SELECTED
THEN PERFORM GET-COUNT THRU GET-EXIT.
.
.
.
This code checks the flag and performs a paragraph that obtains the number of
OldOrders checked and displays it.
CHECK-OLD-ORDER.
INVOKE userObj ″ReadOrder″ RETURNING ORDER-NUMBER.
INVOKE OldOrder ″CreateOldOrder″ USING ORDER-NUMBER
RETURNING META-PARMS.
.
.
.
This code invokes the CreateOldOrder method of the metaclass, which creates
an OldOrder object. We no longer explicitly invoke somNew on the OldOrder
object in the client program.
IF LOST-FLAG = HIGH-VALUE
THEN INVOKE userObj ″WriteLost″ USING ORDER-NUMBER
GO TO CHECK-EXIT.
Here we are merely checking a flag to see if the order was found. If it was not,
we invoke a method in userinterface to write out an appropriate message and
branch to the exit of the performed paragraph.
GET-COUNT.
INVOKE univObj ″somGetClass″ RETURNING metaObj.
INVOKE metaObj ″CountOldOrders″ RETURNING OUT-ORDERS.
INVOKE userObj ″WriteOutCount″ USING OUT-ORDERS.
INVOKE metaObj ″somFree″ .
Get-EXIT.
EXIT.
This method accepts the count from the invoker and displays it with a meaningful
(at least to the system user) literal.
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteLost″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 LS-ORDER-NUMBER PIC 9(5).
PROCEDURE DIVISION USING LS-ORDER-NUMBER.
DISPLAY LS-ORDER-NUMBER ″not on error file″ .
EXIT METHOD.
END METHOD ″WriteLost″ .
In the CountOldOrders method, the code returns the count field to the invoker.
END CLASS MetaOldOrder.
20.3.4.1 Conclusion
After the fourth iteration of our development effort, we have met all known
functional requirements for the business process.
There are many other solutions to this rather simple problem. There are
numerous variations on the class structure presented for this application.
Nonetheless, the exercise illustrates the use of objects implemented in
object-oriented COBOL as applied to a business process in an iterative
development cycle using SOM.
This appendix lists all the source code modules for Example One.
Get-item.
Display ″Enter the item″
Accept Bottle from SYSIN
Move Bottle to User-Bottle.
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteMessage″ .
DATA DIVISION.
Working-Storage Section.
IDENTIFICATION DIVISION.
METHOD-ID. ″RemoveBott″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
01 Found-Flag Pic 9.
88 found VALUE 0.
88 not-found VALUE 1.
Linkage Section.
01 Out-bottle Pic X(20).
01 Delete-flag Pic 9.
PROCEDURE DIVISION USING Out-bottle Delete-flag.
Set not-found to True
Move 1 to Delete-flag
Perform varying sub from 1 by 1
until (sub > 12) or (found)
IF Case-Bottle(sub) = Out-bottle
Move SPACES to Case-Bottle(sub)
Subtract 1 from Case-Count
Move 0 to Delete-flag
Set found to TRUE
END-IF
End-Perform.
Exit method.
END METHOD ″RemoveBott″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″CalculateCost″ .
DATA DIVISION.
Working-Storage Section.
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeCase″ .
ENVIRONMENT DIVISION.
Input-Output Section.
File-Control.
SELECT case-file ASSIGN to CaseData
File Status is Data-key
Organization is Line Sequential.
DATA DIVISION.
File Section.
FD case-file External
Record contains 255.
01 case-record Pic X(255).
Working-Storage Section.
01 Data-key Pic X(2).
01 print-line.
05 print-case-number Pic 9(5).
05 print-case-date Pic X(8).
05 print-case-count Pic 99.
05 print-case-contents.
10 print-case-entry occurs 12 times.
15 print-case-bottle Pic X(20).
PROCEDURE DIVISION.
Open Output case-file
Move case-number to print-case-number.
Move case-date to print-case-date.
Move case-count to print-case-count.
Move case-contents to print-case-contents.
Write case-record FROM print-line.
Close case-file.
Exit method.
END METHOD ″DescribeCase″ .
END CLASS Winecase.
This appendix lists all the source modules for Example Two.
IDENTIFICATION DIVISION.
METHOD-ID. ″AddBott″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
01 Found-Flag Pic 9.
88 found VALUE 0.
88 not-found VALUE 1.
Linkage Section.
01 In-bottle Pic X(20).
01 Add-flag Pic 9.
PROCEDURE DIVISION USING In-bottle Add-flag.
Set not-found to True
Move 1 to Add-flag
Perform varying sub from 1 by 1
until (sub > 12) or (found)
IF Case-Bottle(sub) = SPACES
Move in-bottle to Case-Bottle(sub)
Add 1 to Case-Count
Move 0 to Add-flag
Set found to TRUE
END-IF
End-Perform.
Exit method.
END METHOD ″AddBott″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″RemoveBott″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
01 Found-Flag Pic 9.
88 found VALUE 0.
88 not-found VALUE 1.
Linkage Section.
01 Out-bottle Pic X(20).
01 Delete-flag Pic 9.
PROCEDURE DIVISION USING Out-bottle Delete-flag.
Set not-found to True
Move 1 to Delete-flag
Perform varying sub from 1 by 1
until (sub > 12) or (found)
IDENTIFICATION DIVISION.
METHOD-ID. ″CalculateCost″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
77 cost Pic 9(5)V99.
Linkage Section.
01 Total-cost Pic 9(7)V99.
PROCEDURE DIVISION using Total-cost.
Move 0 to Total-cost
Perform varying sub from 1 by 1
until sub > case-count
ADD 1 to Total-cost
End-Perform.
Exit method.
END METHOD ″CalculateCost″ .
*
*
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCaseNumber″ .
DATA DIVISION.
Linkage Section.
01 Case-num Pic 9(5).
PROCEDURE DIVISION using Case-num.
Move Case-number to Case-num.
Exit method.
END METHOD ″GetCaseNumber″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeCase″ .
ENVIRONMENT DIVISION.
Input-Output Section.
File-Control.
SELECT case-file ASSIGN to CaseData
File Status is Data-key
Organization is Line Sequential.
DATA DIVISION.
File Section.
FD case-file External
Record contains 255.
01 case-record Pic X(255).
Working-Storage Section.
01 Data-key Pic X(2).
01 print-line.
05 print-case-number Pic 9(5).
05 print-case-date Pic X(8).
05 print-case-count Pic 99.
05 print-case-contents.
10 print-case-entry occurs 12 times.
CheckOldCase.
Invoke OldCase ″somNew″ Returning univObj
Invoke userObj ″ReadInput2″ Using Case-number
Invoke univObj ″ReadCase″ Using Case-number flag
Invoke univObj ″CheckBott″ Using Case-contents out-count
Invoke userObj ″WriteStatus″ Using Case-contents out-count
Invoke univObj ″somFree″ .
CreateNewCase.
This appendix lists all the source modules for Example Three.
IDENTIFICATION DIVISION.
METHOD-ID. ″AddBott″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
01 Found-Flag Pic 9.
88 found VALUE 0.
88 not-found VALUE 1.
Linkage Section.
01 In-bottle Pic X(20).
01 Add-flag Pic 9.
PROCEDURE DIVISION USING In-bottle Add-flag.
Set not-found to True
Move 1 to Add-flag
Perform varying sub from 1 by 1
until (sub > 12) or (found)
IF Case-Bottle(sub) = SPACES
Move in-bottle to Case-Bottle(sub)
Add 1 to Case-Count
Move 0 to Add-flag
Set found to TRUE
END-IF
End-Perform.
Exit method.
END METHOD ″AddBott″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″RemoveBott″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
01 Found-Flag Pic 9.
88 found VALUE 0.
88 not-found VALUE 1.
Linkage Section.
01 Out-bottle Pic X(20).
01 Delete-flag Pic 9.
PROCEDURE DIVISION USING Out-bottle Delete-flag.
Set not-found to True
Move 1 to Delete-flag
Perform varying sub from 1 by 1
until (sub > 12) or (found)
IDENTIFICATION DIVISION.
METHOD-ID. ″CalculateCost″ .
DATA DIVISION.
Working-Storage Section.
77 sub Pic 99 VALUE 0.
77 cost Pic 9(5)V99.
Linkage Section.
01 Total-cost Pic 9(7)V99.
PROCEDURE DIVISION using Total-cost.
Move 0 to Total-cost
Perform varying sub from 1 by 1
until sub > case-count
ADD 1 to Total-cost
End-Perform.
Exit method.
END METHOD ″CalculateCost″ .
*
*
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCaseNumber″ .
DATA DIVISION.
Linkage Section.
01 Case-num Pic 9(5).
PROCEDURE DIVISION using Case-num.
Move Case-number to Case-num.
Exit method.
END METHOD ″GetCaseNumber″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeCase″ .
ENVIRONMENT DIVISION.
Input-Output Section.
File-Control.
SELECT case-file ASSIGN to CaseData
File Status is Data-key
Organization is Line Sequential.
DATA DIVISION.
File Section.
FD case-file External
Record contains 255.
01 case-record Pic X(255).
Working-Storage Section.
01 Data-key Pic X(2).
01 print-line.
05 print-case-number Pic 9(5).
05 print-case-date Pic X(8).
05 print-case-count Pic 99.
05 print-case-contents.
10 print-case-entry occurs 12 times.
CheckOldCase.
Invoke userobj ″ReadInput2″ Using Case-number
Invoke OldCase ″CreateOldCase″ Using Case-number univObj.
Perform Until Case-number < 0
Invoke univObj ″CheckBott″ Using Case-Contents out-count
Invoke userObj ″WriteStatus″ Using Case-Contents out-count
Invoke userobj ″ReadInput2″ Using Case-number
Invoke OldCase ″CreateOldCase″ Using Case-number univObj
IDENTIFICATION DIVISION.
CLASS-ID. ″MetaOldCase″ Inherits SOMClass.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS MetaOldCase IS ″MetaOldCase″
CLASS OldCase IS ″OldCase″
CLASS SOMClass IS ″SOMClass″ .
DATA DIVISION.
Working-Storage Section.
01 status-count Pic 99.
PROCEDURE DIVISION.
*
*
*
IDENTIFICATION DIVISION.
METHOD-ID. ″somDefaultInit″ OVERRIDE.
PROCEDURE DIVISION.
Move 0 to status-count.
Exit Method.
END METHOD ″somDefaultInit″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″CreateOldCase″ .
DATA DIVISION.
Linkage Section.
01 Case-number Pic 9(5).
01 anObj USAGE OBJECT REFERENCE.
IDENTIFICATION DIVISION.
CLASS-ID. ″OldCase″ Inherits WineCase MetaClass MetaOldCase.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS MetaOldCase IS ″MetaOldCase″
CLASS OldCase IS ″OldCase″
CLASS WineCase IS ″WineCase″ .
DATA DIVISION.
PROCEDURE DIVISION.
*
*
*
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadCase″ .
ENVIRONMENT DIVISION.
Input-Output Section.
File-Control.
SELECT the-case-file ASSIGN thecase
Organization is Line Sequential.
DATA DIVISION.
File Section.
FD The-case-file External.
01 The-case-record Pic X(255).
Working-Storage Section.
01 the-case.
05 the-case-number Pic 9(5).
05 the-case-date Pic X(8).
05 the-case-count Pic 99.
05 the-case-contents.
10 the-case-entry occurs 12 times.
15 the-case-bottle Pic X(20).
77 eof-flag Pic 9.
88 eof Value 0.
Linkage Section.
01 case-number Pic 9(5).
This appendix lists all the source modules for the first iteration of the Wine Store
Scenario.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS TheOrder IS ″WineOrder″
CLASS UserInterface IS ″UserInterface″ .
DATA DIVISION.
Working-Storage Section.
01 orderObj Usage Object Reference TheOrder.
01 userObj Usage Object Reference UserInterface.
01 Item-Count Pic 9(4).
01 Max-items Pic 9(4) Value 64.
01 Order-number Pic 9(5).
01 Order-date Pic X(8) Value ″00/00/00″.
77 Item-type Pic X(20).
77 Item-cost Pic 999V99.
77 total-cost Pic 9(7)V99.
77 action Pic X(10).
77 Today Pic X(21).
77 flag Pic X(4).
01 WS-items.
05 WS-count Pic 9(4).
05 WS-item Occurs 1 to 64 times
Depending on WS-count
Indexed by WS-Index.
10 WS-type Pic X(20).
10 WS-cost Pic 999V99.
PROCEDURE DIVISION.
Invoke UserInterface ″somNew″ RETURNING userObj
Invoke TheOrder ″somNew″ RETURNING orderObj
End-Perform
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS Bottle IS ″Bottle″
CLASS WineOrder IS ″WineOrder″ .
DATA DIVISION.
Working-Storage Section.
01 Order-Number Pic X(5).
01 Order-date Pic X(8).
01 bottles.
05 Bottle-count Pic 9(4).
05 Bottle-item Occurs 1 to 64 times
Depending on Bottle-count
Indexed by Item-Count.
PROCEDURE DIVISION.
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeOrder″ .
DATA DIVISION.
Working-Storage Section.
01 WS-Type Pic x(20).
01 WS-Cost Pic 999V99.
Linkage Section.
01 LS-Items.
05 LS-Item-Count Pic 9(4).
05 LS-Item Occurs 1 to 64 times
Depending on LS-Item-Count
Indexed by LS-Index.
10 LS-Type Pic x(20).
10 LS-Cost Pic 999V99.
PROCEDURE DIVISION Returning LS-items.
Move Bottle-count to LS-Item-Count
Set LS-Index to 1
Perform varying Item-Count from 1 by 1
until (Item-Count > Bottle-count)
Invoke bottleObj(Item-Count) ″GetCost″
Returning WS-Cost
Move WS-Cost to LS-Cost (LS-Index)
Invoke bottleObj(Item-Count) ″GetType″
Returning WS-Type
Move WS-Type to LS-Type (LS-Index)
Set LS-Index up by 1
End-Perform
Exit method.
END METHOD ″DescribeOrder″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″AddBott″ .
DATA DIVISION.
Working-Storage Section.
01 Found-Flag Pic X(4).
88 found VALUE ″0″.
88 not-found VALUE ″1″.
Linkage Section.
01 LS-Type Pic X(20).
01 LS-Cost Pic 999V99.
01 LS-flag Pic X(4).
PROCEDURE DIVISION USING LS-Type LS-Cost
Returning LS-flag.
Move ″1″ to LS-flag
Found-flag
Perform varying Item-Count from 1 by 1
until (Item-Count > 64) or (found)
IF BottleObj(Item-Count) = NULL
Invoke Bottle ″somNew″
Returning BottleObj(Item-Count)
Invoke bottleObj(Item-Count) ″SetType″
Using LS-Type
Invoke bottleObj(Item-Count) ″SetCost″
Using LS-Cost
Add 1 to Bottle-Count
IDENTIFICATION DIVISION.
METHOD-ID. ″DeleteBott″ .
DATA DIVISION.
Working-Storage Section.
01 Found-Flag Pic X(4).
88 found VALUE ″0″.
88 not-found VALUE ″1″.
Local-Storage Section.
77 Bott-Type Pic X(20).
77 Bott-Cost Pic 999V99.
Linkage Section.
01 LS-Type Pic X(20).
01 LS-Cost Pic 999V99.
01 Delete-flag Pic x(4).
PROCEDURE DIVISION USING LS-Type LS-Cost
Returning Delete-flag.
Move ″1″ to Found-Flag
Delete-flag
Perform varying Item-Count from 1 by 1
until (Item-Count > bottle-count) or (found)
Invoke BottleObj(Item-Count) ″GetType″
Returning Bott-type
If LS-type = Bott-type
Invoke BottleObj(Item-Count) ″GetCost″
Returning Bott-cost
IF LS-Cost = Bott-cost
Set BottleObj(Item-Count) to BottleObj(Bottle-count)
Set BottleObj(bottle-count) to NULL
Subtract 1 from Bottle-Count
Move ″0″ to Delete-flag
Found-Flag
END-IF
END-IF
End-Perform.
Exit method.
END METHOD ″DeleteBott″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″CalculateCost″ .
DATA DIVISION.
Local-Storage Section.
77 cost Pic 999V99.
Linkage Section.
01 LS-Total-cost Pic 9(7)V99.
PROCEDURE DIVISION Returning LS-Total-cost.
Move 0 to LS-Total-cost
Perform varying Item-Count from 1 by 1
until Item-Count > Bottle-count
Invoke bottleObj(Item-Count) ″GetCost″ Returning Cost
ADD Cost to LS-Total-cost
End-Perform.
Exit method.
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderDate″ .
DATA DIVISION.
Linkage Section.
01 LS-Order-Date Pic X(8).
PROCEDURE DIVISION Returning LS-Order-date.
Move Order-date to LS-Order-date.
Exit method.
END METHOD ″GetOrderDate″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderNumber″ .
DATA DIVISION.
Linkage Section.
01 LS-Order-Number Pic X(5).
PROCEDURE DIVISION Returning LS-Order-Number.
Move Order-number to LS-Order-number.
Exit method.
END METHOD ″GetOrderNumber″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″scrapOrder″ .
DATA DIVISION.
Local-Storage Section.
PROCEDURE DIVISION.
Subtract 1 from bottle-Count
Perform varying Item-Count from bottle-count by -1
until (Item-Count = 0)
Invoke bottleObj(Item-Count) ″somFree″
End-Perform
Exit method.
END METHOD ″scrapOrder″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″InitOrder″ .
DATA DIVISION.
Linkage Section.
01 LS-Order-Number Pic X(5).
01 LS-Order-Date Pic X(8).
PROCEDURE DIVISION Using LS-Order-Number LS-Order-Date.
Move LS-Order-Number to Order-number
Move LS-Order-Date to Order-date
Exit Method.
END METHOD ″InitOrder″ .
*
*
END CLASS ″WineOrder″ .
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
DATA DIVISION.
Working-Storage Section.
01 User-action Pic X(10).
88 User-add Value ″Addbott″ .
88 User-delete Value ″Deletebott″ .
88 User-end Value ″End″ .
PROCEDURE DIVISION.
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadAction″ .
DATA DIVISION.
Linkage Section.
01 Action Pic X(10).
PROCEDURE DIVISION Returning Action.
Display ″Enter the action : add, delete, end″
Accept action from SYSIN
Move Function Upper-case(action) to Action
Evaluate action
When ″ADD″
Set User-add to TRUE
When ″DELETE″
Set User-delete to TRUE
When ″END″
Set User-end to TRUE
End-evaluate
Move User-action to action
Exit Method.
END METHOD ″ReadAction″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadType″ .
DATA DIVISION.
Working-Storage Section.
01 WS-type Pic X(80).
Linkage Section.
01 LS-Type Pic X(20).
PROCEDURE DIVISION Returning LS-Type.
Display ″Enter the item″
Accept WS-Type from SYSIN
Move WS-Type(1:20) to LS-Type
Exit Method.
END METHOD ″ReadType″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadCost″ .
DATA DIVISION.
Working-Storage Section.
01 WS-Cost Pic X(6).
Linkage Section.
01 LS-Cost Pic 999V99.
PROCEDURE DIVISION Returning LS-Cost.
Display ″Please enter the cost: ″
Accept WS-Cost from SYSIN
Compute LS-Cost = Function Numval-c (WS-Cost)
Exit Method.
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteMessage″ .
DATA DIVISION.
Linkage Section.
01 LS-Flag Pic X(4).
PROCEDURE DIVISION Using LS-Flag.
IF LS-flag = ″0″
Display user-action ″ successfully completed″
ELSE
Display user-action ″ unsuccessfully completed″
END-IF.
Exit Method.
END METHOD ″WriteMessage″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″Writeoutput″ .
DATA DIVISION.
Working-Storage Section.
77 Formatted-cost Pic $Z,ZZZ,ZZ9.99.
Linkage Section.
01 Total-cost Pic 9(7)V99.
01 Order-number Pic 9(5).
01 Order-date Pic X(8).
PROCEDURE DIVISION Using Total-cost Order-number Order-date.
Move total-cost to Formatted-cost
Display ″Your order costs ″ Formatted-cost
Display ″Your order number is ″ Order-number
Display ″Your order date is ″ Order-date
Exit Method.
END METHOD ″Writeoutput″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″Writebottle″ .
DATA DIVISION.
Working-Storage Section.
01 WS-Formatted-Cost Pic ZZ9.99.
Linkage Section.
01 LS-items.
05 LS-count Pic 9(4).
05 LS-item Occurs 1 to 64 times
Depending on LS-count
Indexed by LS-Index.
10 LS-type Pic X(20).
10 LS-cost Pic 999V99.
ENVIRONMENT DIVISION.
Configuration Section.
Repository.
CLASS SOMObject IS ″SOMObject″
CLASS Bottle IS ″Bottle″ .
DATA DIVISION.
Working-Storage Section.
01 Wine-Type Pic X(20).
01 Wine-cost Pic 999V99.
IDENTIFICATION DIVISION.
METHOD-ID. ″GetType″ .
ENVIRONMENT DIVISION.
DATA DIVISION.
Linkage Section.
01 LS-Type Pic X(20).
PROCEDURE DIVISION Returning LS-Type.
Move Wine-Type to LS-Type
Exit method.
END METHOD ″GetType″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″SetType″ .
ENVIRONMENT DIVISION.
DATA DIVISION.
Linkage Section.
01 LS-Type Pic X(20).
PROCEDURE DIVISION Using LS-Type.
Move LS-Type to Wine-Type
Exit method.
END METHOD ″SetType″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCost″ .
ENVIRONMENT DIVISION.
DATA DIVISION.
Linkage Section.
01 LS-Cost Pic 999V99.
PROCEDURE DIVISION Returning LS-Cost.
Move Wine-Cost to LS-Cost
Exit method.
END METHOD ″GetCost″ .
IDENTIFICATION DIVISION.
METHOD-ID. ″SetCost″ .
ENVIRONMENT DIVISION.
DATA DIVISION.
Linkage Section.
01 LS-Cost Pic 999V99.
PROCEDURE DIVISION Using LS-Cost.
Move LS-Cost to Wine-Cost
Exit method.
IDENTIFICATION DIVISION.
METHOD-ID. ″InitBott″ .
DATA DIVISION.
Linkage Section.
01 LS-Type Pic X(20).
01 LS-Cost Pic 999V99.
PROCEDURE DIVISION Using LS-Type LS-Cost.
Move LS-Type to Wine-Type
Move LS-Cost to Wine-Cost
Exit Method.
END METHOD ″InitBott″ .
*
END CLASS ″Bottle″ .
This appendix lists all the source modules for the second iteration of the Wine
Store Scenario.
****************************************************************
* *
* The client program of the wine application does the *
* following tasks: *
* - Instantiates the UserInterface and WineOrder objects. *
* - Tells the userinterface object to read the user′ s *
* request. *
* - Tells the order object to process the user′ s request *
* and tells the userinterface object to get another *
* request until the user signals the end of the order. *
* If the request is an add or delete, sends the *
* appropriate message to the userinterface object to get *
* the item cost and type, as required by the user′ s *
* processing request. *
* - Tells the order object to compute the order cost. *
* - Tells the order object to get the order number. *
* - Tells the user interface object to write order cost. *
* - Tells the order to describe itself. *
* - Tells the order to write itself to the order file. *
* - Frees the objects it instantiated. *
* - Terminates. *
* *
****************************************************************
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″
CLASS Bottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
CLASS UserInterface IS ″UserInterface″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
* OBJECTS:
01 orderObj USAGE OBJECT REFERENCE WineOrder.
01 userObj USAGE OBJECT REFERENCE UserInterface.
01 bottleObj USAGE OBJECT REFERENCE Bottle.
01 fileObj USAGE OBJECT REFERENCE FileRW.
* DATA ITEMS:
01 ACTION PIC X(10).
01 ITEM-TYPE PIC X(20).
PROCEDURE DIVISION.
****************************************************************
* Invoke the UserInterface class with the inherited somNew *
* method to instantiate a userinterface object. *
* somNew is inherited from SOMObject. *
****************************************************************
INVOKE UserInterface ″somNew″ RETURNING userObj.
****************************************************************
* We will simply use the system date for the order date *
* and generate a random number for the order number. *
* Also we will initialize the item-count field, which will *
* control how many items are placed in the order. *
****************************************************************
MOVE FUNCTION CURRENT-DATE TO ORDER-DATE.
****************************************************************
* Invoke the Order class with the inherited method somNew *
* to instantiate an order object. *
****************************************************************
INVOKE WineOrder ″somNew″ RETURNING orderObj.
****************************************************************
* Invoke the setordernumber and setorderdate methods to *
* set the order′ s date and number. *
****************************************************************
INVOKE orderObj ″SetOrderNumber″ USING ORDER-NUMBER.
INVOKE orderObj ″SetOrderDate″ USING ORDER-DATE.
****************************************************************
* Invoke the userinterface object with ReadAction method. *
****************************************************************
* Loop until the user signals the end of the order. *
****************************************************************
PERFORM UNTIL ACTION = ″END″
OR ITEM-COUNT = MAX-ITEMS
WHEN ″DEL″
* get the type and cost from the user interface
INVOKE userObj ″ReadType″ RETURNING ITEM-TYPE
INVOKE userObj ″ReadCost″ RETURNING ITEM-COST
WHEN OTHER
CONTINUE
END-EVALUATE
INVOKE userObj ″ReadAction″ RETURNING ACTION
****************************************************************
****************************************************************
* Close-out processing follows. *
****************************************************************
****************************************************************
****************************************************************
* If no items were ordered, end the process here. *
****************************************************************
IF ITEM-COUNT = 0
THEN GOBACK.
****************************************************************
* Invoke the order object with the calculate cost method. *
****************************************************************
INVOKE orderObj ″CalculateCost″ RETURNING TOTAL-COST.
****************************************************************
* Invoke the order object with the getordernumber *
* and the getorderdate methods. *
****************************************************************
INVOKE orderObj ″GetOrderNumber″ RETURNING ORDER-NUMBER.
INVOKE orderObj ″GetOrderDate″ RETURNING ORDER-DATE.
****************************************************************
* Invoke the userinterface object with writeoutput method. *
****************************************************************
INVOKE userObj ″WriteOutput″ USING TOTAL-COST
ORDER-NUMBER
ORDER-DATE.
****************************************************************
* Invoke the order object with the describeorder method. *
****************************************************************
INVOKE orderObj ″DescribeOrder″ RETURNING WS-ITEMS.
****************************************************************
* Invoke the userinterface object with writeoutput method. *
****************************************************************
INVOKE userObj ″WriteBottle″ USING WS-ITEMS.
****************************************************************
* Invoke the file object with the xternorder method. *
****************************************************************
INVOKE FileRW ″somNew″ RETURNING fileObj.
INVOKE fileObj ″XternOrder″ USING orderObj.
****************************************************************
* Invoke the instantiated objects with the inherited *
* somDestruct method. *
****************************************************************
INVOKE fileObj ″somFree″ .
****************************************************************
* We′ re outta here... *
****************************************************************
GOBACK.
END PROGRAM ″Wine″ .
****************************************************************
* Class WineOrder : Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class WineOrder contains the following methods: *
* somDefaultInit - Initializes a WineOrder object. *
* somFree - Frees bottles, collection, and order. *
* SetOrderNumber - Sets the number of a WineOrder object *
* based on a given object reference. *
* SetOrderDate - Sets the date of a WineOrder object *
* based on a given object reference. *
* AddBottle - Adds a bottle object to the order *
* RemoveBottle - Removes a bottle object from the *
* order. *
* CalculateCost - Computes the cost of the bottle *
* objects in the order. *
* DescribeOrder - Lists the contents of the bottles *
* collected in the order. *
* GetOrderNumber - Retrieves the number of a WineOrder *
* object. *
* GetOrderDate - Retrieves the date of a WineOrder *
* object. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″
CLASS WineBottle IS ″WineBottle″ .
****************************************************************
* Define the WineOrder Object. *
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EV USAGE POINTER.
****************************************************************
* Define the instance data of the WineOrder Object. *
****************************************************************
01 WINEORDER-OBJECT.
05 WINEORDER-NUMBER PIC X(5).
05 WINEORDER-DATE PIC X(8).
05 WINEORDER-LIST USAGE OBJECT REFERENCE SOMCollection.
****************************************************************
* Define an iterator for use on the wineorder-list. *
****************************************************************
01 WINEORDER-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
EJECT
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* The overridden method somDefaultInit initializes the *
* WineOrder instance, and creates the collection to be *
* used in the order. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somDefaultInit″ OVERRIDE.
DATA DIVISION.
PROCEDURE DIVISION.
****************************************************************
* Initialize the SOM global environment variable. *
****************************************************************
CALL ″somGetGlobalEnvironment″ RETURNING WS-EV.
****************************************************************
* Now initialize an empty collection for us to add bottles *
* into with the addBottle method. *
****************************************************************
INVOKE SOMCollection ″somNew″
RETURNING WINEORDER-LIST.
****************************************************************
* Instantiate an iterator object and associate it with the *
* collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCreateIterator″
USING BY VALUE WS-EV
RETURNING WINEORDER-ITERATOR.
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somDefaultInit″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 ITEM-COUNT PIC S9(8) COMP.
PROCEDURE DIVISION.
****************************************************************
* Get the collected objects. *
****************************************************************
INVOKE WINEORDER-LIST ″somfDeleteAll″
USING BY VALUE WS-EV.
****************************************************************
* Free the list and iterator objects *
****************************************************************
INVOKE WINEORDER-ITERATOR ″somFree″ .
****************************************************************
* Free thyself...Use SUPER so we don′ t recurse back into *
* this method. *
****************************************************************
INVOKE SUPER ″somFree″ .
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somFree″ .
EJECT
****************************************************************
****************************************************************
* Method GetOrderNumber gets the number of WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderNumber″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERNUMBER PIC X(5).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINEORDER-NUMBER TO LS-ORDERNUMBER.
EXIT METHOD.
END METHOD ″GetOrderNumber″ .
EJECT
****************************************************************
****************************************************************
* Method GetOrderDate gets the date of a WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderDate″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERDATE PIC X(8).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINEORDER-DATE TO LS-ORDERDATE.
EXIT METHOD.
END METHOD ″GetOrderDate″ .
EJECT
****************************************************************
****************************************************************
* Method SetOrderNumber sets the number of WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetOrderNumber″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERNUMBER PIC X(5).
****************************************************************
* Move data from the LINKAGE SECTION. *
EXIT METHOD.
END METHOD ″SetOrderNumber″ .
EJECT
****************************************************************
****************************************************************
* Method SetOrderDate sets the date of a WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetOrderDate″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERDATE PIC X(8).
****************************************************************
* Move data from the LINKAGE SECTION. *
****************************************************************
MOVE LS-ORDERDATE TO WINEORDER-DATE.
EXIT METHOD.
END METHOD ″SetOrderDate″ .
EJECT
****************************************************************
****************************************************************
* Method DescribeOrder describes the order contents. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeOrder″ .
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 WS-TYPE PIC X(20).
01 WS-COST PIC 999V99.
01 ITEM-COUNT PIC S9(8) COMP.
LINKAGE SECTION.
01 LS-ITEMS.
05 LS-ITEM-COUNT PIC S9(4).
05 LS-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ITEM-COUNT
INDEXED BY LS-INDEX.
10 LS-TYPE PIC X(20).
10 LS-COST PIC 999V99.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT > 0
THEN SET LS-INDEX TO 1
INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-TYPE-N-COST
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
SET LS-INDEX UP BY 1
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-TYPE-N-COST
END-PERFORM
END-IF.
****************************************************************
* Exit and end the method. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the gettype and getcost methods on the bottle *
* object and move the returned attributes to the table. *
****************************************************************
GET-TYPE-N-COST.
INVOKE CollectedBottle ″GetType″ RETURNING WS-TYPE.
MOVE WS-TYPE TO LS-TYPE (LS-INDEX).
INVOKE CollectedBottle ″GetCost″ RETURNING WS-COST.
MOVE WS-COST TO LS-COST (LS-INDEX).
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 9(7)V99.
****************************************************************
* Initialize the accumulator for the total cost. *
****************************************************************
MOVE ZERO TO LS-COST.
****************************************************************
* Get the count of the number of items in the collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT > 0
INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-COST
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-COST
END-PERFORM
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the getcost method on the bottle object and *
* accumulate the cost. *
****************************************************************
GET-COST.
INVOKE CollectedBottle ″GetCost″ RETURNING WS-COST.
ADD WS-COST TO LS-COST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-BEFORE-COUNT PIC S9(8) COMP.
01 WS-AFTER-COUNT PIC S9(8) COMP.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 theEqualFlag PIC X.
01 ITEM-FOUND-FLAG PIC X.
01 ITEM-COUNT PIC S9(8) COMP.
01 LOOP-COUNT PIC S9(8) COMP.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-BOTTLE USAGE OBJECT REFERENCE WineBottle.
01 LS-PARMS.
05 LS-ITEM-COUNT PIC S9(8) COMP.
05 LS-FLAG PIC X.
****************************************************************
* Get the count of items before adding the object. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-BEFORE-COUNT.
MOVE WS-BEFORE-COUNT TO ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT NOT = 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
****************************************************************
* Add the bottle to the collection if it hasn′ t been *
* added before. *
****************************************************************
IF ITEM-FOUND-FLAG = LOW-VALUE
THEN INVOKE WINEORDER-LIST ″somfAdd″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE.
****************************************************************
* Get the count of items after adding the object. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-AFTER-COUNT.
MOVE WS-AFTER-COUNT TO LS-ITEM-COUNT.
****************************************************************
* If the counts are the same the add failed. *
****************************************************************
IF WS-BEFORE-COUNT = WS-AFTER-COUNT
THEN MOVE ″1″ TO LS-FLAG
ELSE
MOVE ″0″ TO LS-FLAG
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the somfIsEqual method in the bottle object to *
* see if the objects are equal. Set a flag if they are. *
****************************************************************
CHECK-EQUAL.
INVOKE CollectedBottle ″somfIsEqual″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE
RETURNING theEqualFlag.
IF theEqualFlag = HIGH-VALUE
THEN MOVE HIGH-VALUE TO ITEM-FOUND-FLAG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-BEFORE-COUNT PIC S9(8) COMP.
01 WS-AFTER-COUNT PIC S9(8) COMP.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 theEqualFlag PIC X.
01 ITEM-COUNT PIC S9(8) COMP.
01 LOOP-COUNT PIC S9(8) COMP.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-BOTTLE USAGE OBJECT REFERENCE WineBottle.
01 LS-PARMS.
05 LS-ITEM-COUNT PIC S9(8) COMP.
05 LS-FLAG PIC X.
****************************************************************
* Get the count of items before the delete. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-BEFORE-COUNT.
MOVE WS-BEFORE-COUNT TO ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT NOT = 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL-N-REMOVE
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM VARYING LOOP-COUNT
FROM 1 BY 1
UNTIL LOOP-COUNT > ITEM-COUNT
OR theEqualFlag = HIGH-VALUE
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL-N-REMOVE
END-PERFORM
****************************************************************
* Get the count of items after the delete. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-AFTER-COUNT.
MOVE WS-AFTER-COUNT TO LS-ITEM-COUNT.
****************************************************************
* If the counts are the same the delete failed. *
****************************************************************
IF WS-BEFORE-COUNT = WS-AFTER-COUNT
THEN MOVE ″1″ TO LS-FLAG
ELSE
MOVE ″0″ TO LS-FLAG
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
CHECK-EQUAL-N-REMOVE.
INVOKE CollectedBottle ″somfIsEqual″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE
RETURNING theEqualFlag.
****************************************************************
* If we find one, remove it from the list. *
****************************************************************
IF theEqualFlag = HIGH-VALUE
THEN INVOKE WINEORDER-LIST ″somfRemove″
USING BY VALUE WS-EV
BY VALUE CollectedBottle
INVOKE CollectedBottle ″somFree″ .
****************************************************************
* Class UserInterface: Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″ .
****************************************************************
* Define the UserInterface Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the instance data of the UserInterface Object. *
****************************************************************
01 USER-ACTION PIC X(10).
88 UA-ADD VALUE ″Add″ .
88 UA-DELETE VALUE ″Delete″ .
88 UA-END VALUE ″End″ .
EJECT
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method ReadAction gets the system user′ s command to be *
* processed. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadAction″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TYPE PIC X(80).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
01 WS-COST-WORK PIC X(6).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-FLAG PIC X.
IF LS-FLAG = ″0″
THEN DISPLAY USER-ACTION ″successful ″
ELSE
DISPLAY USER-ACTION ″failed ″
END-IF.
EXIT METHOD.
END METHOD ″WriteMessage″ .
EJECT
****************************************************************
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FORMATTED-COST PIC $Z,ZZZ,ZZ9.99.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TOTAL-COST PIC 9(7)V99.
01 LS-ORDER-NUMBER PIC 9(5).
01 LS-ORDER-DATE PIC X(8).
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ITEMS.
05 LS-ITEM-COUNT PIC S9(4).
05 LS-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ITEM-COUNT
INDEXED BY LS-INDEX.
10 LS-TYPE PIC X(20).
10 LS-COST PIC 999V99.
****************************************************************
* Class WineBottle : Inherits from somf_MCollectible *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class WineBottle contains the following methods: *
* somfIsEqual - Provides SOM a method to see if two *
* objects are equivalent. *
* SetCost - Sets the cost of a WineBottle object *
* based on a given object reference. *
* SetType - Sets the type of a WineBottle object *
* based on a given object reference. *
* GetCost - Retrieves the cost of a WineBottle *
* object based on a given object *
* reference. *
* GetType - Retrieves the type of a WineBottle *
* object based on a given object *
* reference. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS WineBottle IS ″WineBottle″
CLASS somf-MCollectible IS ″somf_MCollectible″ .
****************************************************************
* Define the WineBottle Object. *
****************************************************************
****************************************************************
* Define the instance data of the WineBottle Object. *
****************************************************************
01 WINEBOTTLE-OBJECT.
05 WINE-TYPE PIC X(20).
05 WINE-COST PIC 999V99.
EJECT
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method somfIsEqual provides SOM a method to see if two *
* bottle objects are equivalent. In our case, if their *
* types and costs are the same, we consider them equal. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somfIsEqual″ OVERRIDE.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 ITEMTYPE PIC X(20).
01 ITEMCOST PIC 999V99.
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
01 theBottle Usage Object Reference WineBottle.
01 theEqualFlag PIC X.
****************************************************************
* Get the type and cost of the bottle object *
****************************************************************
INVOKE theBottle ″GetType″ RETURNING ITEMTYPE.
INVOKE theBottle ″GetCost″ RETURNING ITEMCOST.
****************************************************************
* Get those just obtained to the attributes of this *
* instance. If they are equal, set the equality flag *
* to a binary 1, else set it to a low-value. *
****************************************************************
IF (WINE-TYPE = ITEMTYPE) AND
(WINE-COST = ITEMCOST)
THEN MOVE HIGH-VALUE TO theEqualFlag
ELSE
MOVE LOW-VALUE TO theEqualFlag.
EXIT METHOD.
END METHOD ″somfIsEqual″ .
EJECT
****************************************************************
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINE-TYPE TO LS-TYPE.
EXIT METHOD.
END METHOD ″GetType″ .
EJECT
****************************************************************
****************************************************************
* Method GetCost Gets the COST of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCost″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINE-COST TO LS-COST.
EXIT METHOD.
END METHOD ″GetCost″ .
EJECT
****************************************************************
****************************************************************
* Method SetType Sets the type of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetType″ .
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE LS-TYPE TO WINE-TYPE.
EXIT METHOD.
END METHOD ″SetType″ .
EJECT
****************************************************************
****************************************************************
* Method SetCost Sets the COST of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetCost″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE LS-COST TO WINE-COST.
EXIT METHOD.
END METHOD ″SetCost″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class WineBottle. *
****************************************************************
END CLASS ″WineBottle″ .
****************************************************************
* Class FileRW : Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class FileRW contains the following methods: *
* XternOrder - Externalizes an order to a flat *
* file. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″ .
****************************************************************
* Define the FileRW object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method XternOrder writes the order to a flat file. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″XternOrder″ .
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ORDERS ASSIGN TO ORDERS
FILE STATUS IS WS-STATUS-FLAG
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD ORDERS EXTERNAL
RECORD CONTAINS 255.
01 ORDER-RECORD PIC X(255).
LINKAGE SECTION.
01 orderObj USAGE OBJECT REFERENCE WineOrder.
****************************************************************
* Open the flat file for output. *
****************************************************************
OPEN OUTPUT ORDERS.
MOVE SPACES TO WS-ORDER-RECORD.
****************************************************************
* Write the record. *
****************************************************************
WRITE ORDER-RECORD FROM WS-ORDER-RECORD.
****************************************************************
* Close the order file after writing the record to it. *
****************************************************************
CLOSE ORDERS.
EXIT METHOD.
END METHOD ″XternOrder″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class FileRW. *
****************************************************************
END CLASS ″FileRW″ .
This appendix lists all the source modules for the third iteration of the Wine
Store Scenario.
****************************************************************
* *
* The client program of the wine application does the *
* following tasks: *
* - Instantiates the UserInterface obejct. *
* - If a status request: *
* -- instantiates an OldOrder object *
* -- invokes the UserInterface object to get the order *
* number *
* -- invokes the OldOrder to report out-of-stock items *
* -- invokes the UserInterface object to display the *
* status of the out-of-stock items *
* -- Frees the OldOrder object *
* - If a request for a new order: *
* -- Tells the order object to process the user′ s request *
* and tells the userinterface object to get another *
* request until the user signals the end of the order. *
* If the request is an add or delete, sends the *
* appropriate message to the userinterface object for *
* the item cost and type, as required by the user′ s *
* processing request. *
* -- Tells the order object to compute the order cost. *
* -- Tells the order object to get the order number. *
* -- Tells the user interface object to write order cost. *
* -- Tells the order to describe itself. *
* -- Tells the order to write itself to the order file. *
* -- Frees the objects it instantiated. *
* - Frees the UserInterface object. *
* - Terminates. *
* *
****************************************************************
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″
CLASS OldOrder IS ″OldOrder″
CLASS Bottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
CLASS UserInterface IS ″UserInterface″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
* DATA ITEMS:
01 ACTION PIC X(10).
01 PROCESS PIC X(10).
01 ITEM-TYPE PIC X(20).
01 ITEM-COST PIC 999V99.
01 MAX-ITEMS PIC 9(4) COMP VALUE 64.
01 WS-PARMS.
05 ITEM-COUNT PIC S9(8) COMP.
05 WS-FLAG PIC X.
88 SUCCESSFUL VALUE ″0″.
88 FAILURE VALUE ″1″.
01 WS-ORDER-RECORD.
05 WSO-ORDER-NUMBER PIC X(5).
05 WSO-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 WSO-ITEMS.
10 WSO-ORDER-COUNT PIC S9(4).
10 WSO-ORDER-ITEM OCCURS 1 TO 64
DEPENDING ON WSO-ORDER-COUNT
INDEXED BY WSO-INDEX.
15 WSO-TYPE PIC X(20).
15 WSO-COST PIC 999V99.
EJECT
PROCEDURE DIVISION.
****************************************************************
* Invoke the UserInterface class with the inherited somNew *
* method to instantiate a userinterface object. *
* somNew is inherited from SOMObject. *
****************************************************************
* Invoke the UserInterface class with the ReadProcess *
* method to obtain the process desired by the system user. *
****************************************************************
INVOKE userObj ″ReadProcess″ RETURNING PROCESS.
****************************************************************
* Use the process to control the path through this program. *
****************************************************************
PERFORM UNTIL PROCESS (1:4) = ″EXIT″
EVALUATE PROCESS (1:3)
WHEN ″STA″
PERFORM CHECK-OLD-ORDER THRU CHECK-EXIT
WHEN ″NEW″
PERFORM CREATE-NEW-ORDER THRU CREATE-EXIT
WHEN OTHER
CONTINUE
END-EVALUATE
INVOKE userObj ″ReadProcess″ RETURNING PROCESS
END-PERFORM.
****************************************************************
* Free the user interface object we created. *
****************************************************************
INVOKE userObj ″somFree″ .
****************************************************************
* We′ re outta here... *
****************************************************************
GOBACK.
EJECT
CHECK-OLD-ORDER.
****************************************************************
* Invoke the old order class with the inherited method *
* somNew to instantiate an old order object and an order *
* object. *
****************************************************************
INVOKE OldOrder ″somNew″ RETURNING oldOrderObj.
****************************************************************
* Invoke the userinterface object with ReadOrder method. *
****************************************************************
INVOKE userObj ″ReadOrder″ RETURNING ORDER-NUMBER.
****************************************************************
* Invoke the oldorder object to check the status of *
* ordered items. *
****************************************************************
INVOKE oldOrderObj ″CheckItems″ USING ORDER-NUMBER
RETURNING OUT-ITEMS.
****************************************************************
* Invoke the userinterface object to write the status of *
* out-of-stock items. *
****************************************************************
INVOKE userObj ″WriteStatus″ USING OUT-ITEMS.
CHECK-EXIT.
EXIT.
EJECT
CREATE-NEW-ORDER.
****************************************************************
* We will simply use the system date for the order date *
* and generate a random number for the order number. *
* Also we will initialize the item-count field, which will *
* control how many items are placed in the order. *
****************************************************************
MOVE FUNCTION CURRENT-DATE TO ORDER-DATE.
****************************************************************
* Invoke the Order class with the inherited method somNew *
* to instantiate an order object. *
****************************************************************
INVOKE WineOrder ″somNew″ RETURNING orderObj.
****************************************************************
* Invoke the setordernumber and setorderdate methods to *
* set the order′ s date and number. *
****************************************************************
INVOKE orderObj ″SetOrderNumber″ USING ORDER-NUMBER.
INVOKE orderObj ″SetOrderDate″ USING ORDER-DATE.
****************************************************************
* Invoke the userinterface object with ReadAction method. *
****************************************************************
INVOKE userObj ″ReadAction″ RETURNING ACTION.
****************************************************************
* Loop until the user signals the end of the order. *
****************************************************************
PERFORM UNTIL ACTION (1:3) = ″END″
OR ITEM-COUNT = MAX-ITEMS
WHEN ″DEL″
* get the type and cost from the user interface
INVOKE userObj ″ReadType″ RETURNING ITEM-TYPE
INVOKE userObj ″ReadCost″ RETURNING ITEM-COST
WHEN OTHER
CONTINUE
END-EVALUATE
INVOKE userObj ″ReadAction″ RETURNING ACTION
END-PERFORM.
****************************************************************
* End of loop. *
****************************************************************
****************************************************************
* Close-out processing follows. *
****************************************************************
****************************************************************
* If no items were ordered, end the process here. *
****************************************************************
IF ITEM-COUNT = 0
****************************************************************
* Free the order object we created. *
****************************************************************
THEN INVOKE orderObj ″somFree″
GO TO CREATE-EXIT
END-IF.
****************************************************************
* Invoke the order object with the getordernumber *
* and the getorderdate methods. *
****************************************************************
INVOKE orderObj ″GetOrderNumber″ RETURNING ORDER-NUMBER.
INVOKE orderObj ″GetOrderDate″ RETURNING ORDER-DATE.
****************************************************************
* Invoke the userinterface object with writeoutput method. *
****************************************************************
INVOKE userObj ″WriteOutput″ USING TOTAL-COST
ORDER-NUMBER
ORDER-DATE.
****************************************************************
* Invoke the order object with the describeorder method. *
****************************************************************
INVOKE orderObj ″DescribeOrder″ RETURNING WS-ITEMS.
****************************************************************
* Invoke the userinterface object with writeoutput method. *
****************************************************************
INVOKE userObj ″WriteBottle″ USING WS-ITEMS.
****************************************************************
* Create a filereadwrite object with the inherited somNew *
* method. *
****************************************************************
INVOKE FileRW ″somNew″ RETURNING fileObj.
****************************************************************
* Invoke the file object with the xternorder method. *
****************************************************************
INVOKE fileObj ″XternOrder″ USING orderObj.
****************************************************************
* Free the filereadwrite object we created. *
****************************************************************
INVOKE fileObj ″somFree″ .
****************************************************************
* Free the order object we created. *
****************************************************************
INVOKE orderObj ″somFree″ .
CREATE-EXIT.
EXIT.
END PROGRAM ″Wine″ .
****************************************************************
* Class WineOrder : Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class WineOrder contains the following methods: *
* somDefaultInit - Initializes a WineOrder object. *
* somFree - Frees bottles, collection, and order. *
* SetOrderNumber - Sets the number of a WineOrder object *
* based on a given object reference. *
* SetOrderDate - Sets the date of a WineOrder object *
* based on a given object reference. *
* AddBottle - Adds a bottle object to the order *
* RemoveBottle - Removes a bottle object from the *
* order. *
* CalculateCost - Computes the cost of the bottle *
* objects in the order. *
* DescribeOrder - Lists the contents of the bottles *
* collected in the order. *
* GetOrderNumber - Retrieves the number of a WineOrder *
* object. *
* GetOrderDate - Retrieves the date of a WineOrder *
* object. *
* SetInstanceData- Sets all the attributes of an order *
* object. *
* GetInstanceData- Gets all the attributes of an order *
* object. *
* GetEV - Retrieves the SOM environment *
* variable. *
* GetList - Retrieves the SOM list for the *
* collected order items. *
* GetIterator - Retrieves the SOM iterator for the *
* collected order items. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″
CLASS WineBottle IS ″WineBottle″ .
****************************************************************
* Define the WineOrder Object. *
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EV USAGE POINTER.
****************************************************************
* Define the instance data of the WineOrder Object. *
****************************************************************
01 WINEORDER-OBJECT.
05 WINEORDER-NUMBER PIC X(5).
05 WINEORDER-DATE PIC X(8).
05 WINEORDER-LIST USAGE OBJECT REFERENCE SOMCollection.
****************************************************************
* Define an iterator for use on the wineorder-list. *
****************************************************************
01 WINEORDER-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
EJECT
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* The overridden method somDefaultInit initializes the *
* WineOrder instance, and creates the collection to be *
* used in the order. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somDefaultInit″ OVERRIDE.
DATA DIVISION.
PROCEDURE DIVISION.
****************************************************************
* Initialize the SOM global environment variable. *
****************************************************************
CALL ″somGetGlobalEnvironment″ RETURNING WS-EV.
****************************************************************
* Now initialize an empty collection for us to add bottles *
* into with the addBottle method. *
****************************************************************
INVOKE SOMCollection ″somNew″
RETURNING WINEORDER-LIST.
****************************************************************
* Instantiate an iterator object and associate it with the *
* collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCreateIterator″
USING BY VALUE WS-EV
RETURNING WINEORDER-ITERATOR.
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somDefaultInit″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 ITEM-COUNT PIC S9(8) COMP.
PROCEDURE DIVISION.
****************************************************************
* Get the collected objects. *
****************************************************************
INVOKE WINEORDER-LIST ″somfDeleteAll″
USING BY VALUE WS-EV.
****************************************************************
* Free the list and iterator objects *
****************************************************************
INVOKE WINEORDER-ITERATOR ″somFree″ .
****************************************************************
* Free thyself...Use SUPER so we don′ t recurse back into *
* this method. *
****************************************************************
INVOKE SUPER ″somFree″ .
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somFree″ .
EJECT
****************************************************************
****************************************************************
* Method GetOrderNumber gets the number of WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderNumber″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERNUMBER PIC X(5).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINEORDER-NUMBER TO LS-ORDERNUMBER.
EXIT METHOD.
END METHOD ″GetOrderNumber″ .
EJECT
****************************************************************
****************************************************************
* Method GetOrderDate gets the date of a WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderDate″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERDATE PIC X(8).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINEORDER-DATE TO LS-ORDERDATE.
EXIT METHOD.
END METHOD ″GetOrderDate″ .
EJECT
****************************************************************
****************************************************************
* Method SetOrderNumber sets the number of WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetOrderNumber″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERNUMBER PIC X(5).
****************************************************************
* Move data from the LINKAGE SECTION. *
EXIT METHOD.
END METHOD ″SetOrderNumber″ .
EJECT
****************************************************************
****************************************************************
* Method SetOrderDate sets the date of a WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetOrderDate″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERDATE PIC X(8).
****************************************************************
* Move data from the LINKAGE SECTION. *
****************************************************************
MOVE LS-ORDERDATE TO WINEORDER-DATE.
EXIT METHOD.
END METHOD ″SetOrderDate″ .
EJECT
****************************************************************
****************************************************************
* Method DescribeOrder describes the order contents. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeOrder″ .
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 WS-TYPE PIC X(20).
01 WS-COST PIC 999V99.
01 ITEM-COUNT PIC S9(8) COMP.
LINKAGE SECTION.
01 LS-ITEMS.
05 LS-ITEM-COUNT PIC S9(4).
05 LS-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ITEM-COUNT
INDEXED BY LS-INDEX.
10 LS-TYPE PIC X(20).
10 LS-COST PIC 999V99.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT > 0
THEN SET LS-INDEX TO 1
INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-TYPE-N-COST
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
SET LS-INDEX UP BY 1
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-TYPE-N-COST
END-PERFORM
END-IF.
****************************************************************
* Exit and end the method. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the gettype and getcost methods on the bottle *
* object and move the returned attributes to the table. *
****************************************************************
GET-TYPE-N-COST.
INVOKE CollectedBottle ″GetType″ RETURNING WS-TYPE.
MOVE WS-TYPE TO LS-TYPE (LS-INDEX).
INVOKE CollectedBottle ″GetCost″ RETURNING WS-COST.
MOVE WS-COST TO LS-COST (LS-INDEX).
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 9(7)V99.
****************************************************************
* Initialize the accumulator for the total cost. *
****************************************************************
MOVE ZERO TO LS-COST.
****************************************************************
* Get the count of the number of items in the collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT > 0
INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-COST
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-COST
END-PERFORM
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the getcost method on the bottle object and *
* accumulate the cost. *
****************************************************************
GET-COST.
INVOKE CollectedBottle ″GetCost″ RETURNING WS-COST.
ADD WS-COST TO LS-COST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-BEFORE-COUNT PIC S9(8) COMP.
01 WS-AFTER-COUNT PIC S9(8) COMP.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 theEqualFlag PIC X.
01 ITEM-FOUND-FLAG PIC X.
01 ITEM-COUNT PIC S9(8) COMP.
01 LOOP-COUNT PIC S9(8) COMP.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-BOTTLE USAGE OBJECT REFERENCE WineBottle.
01 LS-PARMS.
05 LS-ITEM-COUNT PIC S9(8) COMP.
05 LS-FLAG PIC X.
****************************************************************
* Get the count of items before adding the object. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-BEFORE-COUNT.
MOVE WS-BEFORE-COUNT TO ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT NOT = 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
****************************************************************
* Add the bottle to the collection if it hasn′ t been *
* added before. *
****************************************************************
IF ITEM-FOUND-FLAG = LOW-VALUE
THEN INVOKE WINEORDER-LIST ″somfAdd″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE.
****************************************************************
* Get the count of items after adding the object. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-AFTER-COUNT.
MOVE WS-AFTER-COUNT TO LS-ITEM-COUNT.
****************************************************************
* If the counts are the same the add failed. *
****************************************************************
IF WS-BEFORE-COUNT = WS-AFTER-COUNT
THEN MOVE ″1″ TO LS-FLAG
ELSE
MOVE ″0″ TO LS-FLAG
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the somfIsEqual method in the bottle object to *
* see if the objects are equal. Set a flag if they are. *
****************************************************************
CHECK-EQUAL.
INVOKE CollectedBottle ″somfIsEqual″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE
RETURNING theEqualFlag.
IF theEqualFlag = HIGH-VALUE
THEN MOVE HIGH-VALUE TO ITEM-FOUND-FLAG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-BEFORE-COUNT PIC S9(8) COMP.
01 WS-AFTER-COUNT PIC S9(8) COMP.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 theEqualFlag PIC X.
01 ITEM-COUNT PIC S9(8) COMP.
01 LOOP-COUNT PIC S9(8) COMP.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-BOTTLE USAGE OBJECT REFERENCE WineBottle.
01 LS-PARMS.
05 LS-ITEM-COUNT PIC S9(8) COMP.
05 LS-FLAG PIC X.
****************************************************************
* Get the count of items before the delete. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-BEFORE-COUNT.
MOVE WS-BEFORE-COUNT TO ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT NOT = 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL-N-REMOVE
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM VARYING LOOP-COUNT
FROM 1 BY 1
UNTIL LOOP-COUNT > ITEM-COUNT
OR theEqualFlag = HIGH-VALUE
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL-N-REMOVE
END-PERFORM
****************************************************************
* Get the count of items after the delete. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-AFTER-COUNT.
MOVE WS-AFTER-COUNT TO LS-ITEM-COUNT.
****************************************************************
* If the counts are the same the delete failed. *
****************************************************************
IF WS-BEFORE-COUNT = WS-AFTER-COUNT
THEN MOVE ″1″ TO LS-FLAG
ELSE
MOVE ″0″ TO LS-FLAG
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
CHECK-EQUAL-N-REMOVE.
INVOKE CollectedBottle ″somfIsEqual″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE
RETURNING theEqualFlag.
****************************************************************
* If we find one, remove it from the list. *
****************************************************************
IF theEqualFlag = HIGH-VALUE
THEN INVOKE WINEORDER-LIST ″somfRemove″
USING BY VALUE WS-EV
BY VALUE CollectedBottle
INVOKE CollectedBottle ″somFree″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
****************************************************************
EXIT METHOD.
END METHOD ″GetEV″ .
EJECT
****************************************************************
****************************************************************
* Method GetList gets the wineorder list collection. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetList″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-LIST USAGE OBJECT REFERENCE SOMCollection.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
SET LS-LIST TO WINEORDER-LIST.
EXIT METHOD.
END METHOD ″GetList″ .
EJECT
****************************************************************
****************************************************************
* Method GetIterator gets the wineorder list iterator. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetIterator″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
SET LS-ITERATOR TO WINEORDER-ITERATOR.
EXIT METHOD.
END METHOD ″GetIterator″ .
EJECT
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PARMS.
05 ITEM-COUNT PIC S9(8) COMP.
05 WS-FLAG PIC X.
88 SUCCESSFUL VALUE ″0″.
88 FAILURE VALUE ″1″.
01 bottleObj USAGE OBJECT REFERENCE WineBottle.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER.
05 LS-ORDER-NUMBER PIC X(5).
05 LS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 LS-ORDER-COUNT PIC S9(4).
05 LS-ORDER-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ORDER-COUNT
INDEXED BY LS-INDEX.
10 LSO-TYPE PIC X(20).
10 LSO-COST PIC 999V99.
****************************************************************
* Move in the easy stuff... *
****************************************************************
INVOKE self ″SetOrderNumber″ USING LS-ORDER-NUMBER.
INVOKE self ″SetOrderDate″ USING LS-ORDER-DATE.
****************************************************************
* And now the tricky stuff... *
****************************************************************
PERFORM VARYING LS-INDEX FROM 1 BY 1
UNTIL LS-INDEX > LS-ORDER-COUNT
INVOKE WineBottle ″somNew″ RETURNING bottleObj
INVOKE bottleObj ″SetType″ USING LSO-TYPE (LS-INDEX)
INVOKE bottleObj ″SetCost″ USING LSO-COST (LS-INDEX)
INVOKE self ″AddBottle″ USING bottleObj
RETURNING WS-PARMS
END-PERFORM.
EXIT METHOD.
END METHOD ″SetInstanceData″ .
EJECT
****************************************************************
****************************************************************
* Method GetInstanceData retrieves all the attributes of an *
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER.
05 LS-ORDER-NUMBER PIC X(5).
05 LS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 LS-ITEMS.
10 LS-ORDER-COUNT PIC S9(4).
10 LS-ORDER-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ORDER-COUNT
INDEXED BY LS-INDEX.
15 LSO-TYPE PIC X(20).
15 LSO-COST PIC 999V99.
EXIT METHOD.
END METHOD ″GetInstanceData″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class WineOrder. *
****************************************************************
END CLASS ″WineOrder″ .
****************************************************************
* Class OldOrder : Inherits from the WineOrder class. *
****************************************************************
****************************************************************
* Class OldOrder contains the following methods: *
* CheckItems - Checks the status of ordered items. *
* somFree - Overridden method that invokes *
* destructor in parent class. *
****************************************************************
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS OldOrder IS ″OldOrder″
CLASS WineOrder IS ″WineOrder″
CLASS WineBottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″ .
DATA DIVISION.
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method CheckItems checks to see if an item is in stock *
* or not. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″CheckItems″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 WINEORDER-LIST USAGE OBJECT REFERENCE SOMCollection.
01 WINEORDER-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
01 fileObj USAGE OBJECT REFERENCE FileRW.
01 WS-FLAG PIC X.
88 OUT-OF-STOCK VALUE ″0″.
88 IN-STOCK VALUE ″1″.
01 WS-TYPE PIC X(20).
01 WS-COST PIC 999V99.
01 WS-EV USAGE POINTER.
01 ITEM-COUNT PIC S9(8) COMP.
01 WS-ORDER-RECORD.
05 WSO-ORDER-NUMBER PIC X(5).
05 WSO-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 WSO-ITEMS.
10 WSO-ORDER-COUNT PIC S9(4).
10 WSO-ORDER-ITEM OCCURS 1 TO 64
DEPENDING ON WSO-ORDER-COUNT
INDEXED BY WSO-INDEX.
15 WSOR-TYPE PIC X(20).
15 WSOR-COST PIC 999V99.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER-NUMBER PIC X(5).
01 LS-OUT-ITEMS.
****************************************************************
* Create a filereadwrite object with the inherited somNew *
* method. *
****************************************************************
INVOKE FileRW ″somNew″ RETURNING fileObj.
****************************************************************
* Invoke the file object with the xreadorder method. *
****************************************************************
INVOKE fileObj ″XReadOrder″ USING LS-ORDER-NUMBER
RETURNING WS-ORDER-RECORD.
****************************************************************
* Free the filereadwrite object we created. *
****************************************************************
INVOKE fileObj ″somFree″ .
****************************************************************
* Set the instance data in the order object with the data *
* returned from the file object. *
****************************************************************
INVOKE self ″SetInstanceData″ USING WS-ORDER-RECORD.
****************************************************************
* Get the SOM environment variable, and the som collection *
* from the parent object so we can use them here. *
****************************************************************
INVOKE self ″GetEV″ RETURNING WS-EV.
INVOKE self ″GetList″ RETURNING WINEORDER-LIST.
INVOKE self ″GetIterator″
RETURNING WINEORDER-ITERATOR.
****************************************************************
* Get the count of the number of items in the collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
MOVE ZERO TO LS-OUT-COUNT.
SET LS-INDEX TO 1.
IF ITEM-COUNT > 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-STATUS
EXIT METHOD.
****************************************************************
* Check the inventory status of the bottle by invoking its *
* GetStatus. If it′ s out of stock, move it to the table *
* and increment the out of stock counter. *
****************************************************************
CHECK-STATUS.
INVOKE CollectedBottle ″GetStatus″
RETURNING WS-FLAG.
IF OUT-OF-STOCK
THEN ADD 1 TO LS-OUT-COUNT
INVOKE CollectedBottle ″GetType″
RETURNING WS-TYPE
MOVE WS-TYPE TO LSO-TYPE (LS-INDEX)
INVOKE CollectedBottle ″GetCost″
RETURNING WS-COST
MOVE WS-COST TO LSO-COST (LS-INDEX)
SET LS-INDEX UP BY 1.
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somFree″ .
SKIP3
SKIP3
****************************************************************
****************************************************************
* Class UserInterface: Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class UserInterface contains the following methods: *
* ReadAction - Gets the input command from the *
* system user. *
* ReadType - Gets the type of item from the *
* system user. *
* ReadCost - Gets the cost of item from the *
* system user. *
* WriteMessage - Displays a system status message to *
* the system user. *
* WriteOutput - Displays the cost of the order and *
* order to the system user. *
* WriteBottle - Displays the attributes of a bottle *
* collected in the order. *
* ReadProcess - Gets the processing request from the *
* system user. *
* ReadOrder - Gets the order number from the system *
* user. *
* WriteStatus - Displays the inventory status of *
* ordered items to the system user. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″ .
****************************************************************
* Define the UserInterface Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method ReadAction gets the system user′ s command to be *
* processed. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadAction″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ACTION PIC X(10).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TYPE PIC X(80).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
01 WS-COST-WORK PIC X(6).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-FLAG PIC X.
IF LS-FLAG = ″0″
THEN DISPLAY USER-ACTION ″successful ″
ELSE
DISPLAY USER-ACTION ″failed ″
END-IF.
EXIT METHOD.
END METHOD ″WriteMessage″ .
EJECT
****************************************************************
****************************************************************
* Method WriteOutput displays the order number and cost *
* to the system user. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteOutput″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FORMATTED-COST PIC $Z,ZZZ,ZZ9.99.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TOTAL-COST PIC 9(7)V99.
01 LS-ORDER-NUMBER PIC 9(5).
01 LS-ORDER-DATE PIC X(8).
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ITEMS.
05 LS-ITEM-COUNT PIC S9(4).
05 LS-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ITEM-COUNT
INDEXED BY LS-INDEX.
10 LS-TYPE PIC X(20).
10 LS-COST PIC 999V99.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-PROCESS PIC X(10).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
01 WS-ORDER PIC X(5).
01 WS-ORDER-9 PIC 9(5).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER PIC X(5).
EXIT METHOD.
END METHOD ″ReadOrder″ .
EJECT
****************************************************************
****************************************************************
* Method WriteStatus displays the inventory attributes and *
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-OUT-ITEMS.
05 LS-OUT-COUNT PIC S9(4).
05 LS-OUT-ITEM OCCURS 1 to 64 TIMES
DEPENDING ON LS-OUT-COUNT
INDEXED BY LS-INDEX.
10 LSO-TYPE PIC X(20).
10 LSO-COST PIC 999V99.
IF LS-OUT-COUNT > 0
THEN DISPLAY ″LIST OUT OF STOCK ITEMS: ″
INVOKE SELF ″WriteBottle″
USING LS-OUT-ITEMS
ELSE
DISPLAY ″ALL ITEMS IN STOCK!″ .
EXIT METHOD.
END METHOD ″WriteStatus″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class UserInterface. *
****************************************************************
END CLASS ″UserInterface″ .
****************************************************************
* Class WineBottle : Inherits from somf_MCollectible *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class WineBottle contains the following methods: *
* somfIsEqual - Provides SOM a method to see if two *
* objects are equivalent. *
* SetCost - Sets the cost of a WineBottle object *
* based on a given object reference. *
* SetType - Sets the type of a WineBottle object *
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS WineBottle IS ″WineBottle″
CLASS somf-MCollectible IS ″somf_MCollectible″ .
****************************************************************
* Define the WineBottle Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the instance data of the WineBottle Object. *
****************************************************************
01 WINEBOTTLE-OBJECT.
05 WINE-TYPE PIC X(20).
05 WINE-COST PIC 999V99.
EJECT
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method somfIsEqual provides SOM a method to see if two *
* bottle objects are equivalent. In our case, if their *
* types and costs are the same, we consider them equal. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somfIsEqual″ OVERRIDE.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 ITEMTYPE PIC X(20).
01 ITEMCOST PIC 999V99.
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
01 theBottle Usage Object Reference WineBottle.
01 theEqualFlag PIC X.
****************************************************************
* Get the type and cost of the bottle object *
****************************************************************
INVOKE theBottle ″GetType″ RETURNING ITEMTYPE.
INVOKE theBottle ″GetCost″ RETURNING ITEMCOST.
****************************************************************
* Get those just obtained to the attributes of this *
* instance. If they are equal, set the equality flag *
* to a binary 1, else set it to a low-value. *
****************************************************************
IF (WINE-TYPE = ITEMTYPE) AND
(WINE-COST = ITEMCOST)
THEN MOVE HIGH-VALUE TO theEqualFlag
ELSE
MOVE LOW-VALUE TO theEqualFlag.
EXIT METHOD.
END METHOD ″somfIsEqual″ .
EJECT
****************************************************************
****************************************************************
* Method GetType Gets the type of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetType″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINE-TYPE TO LS-TYPE.
EXIT METHOD.
END METHOD ″GetType″ .
EJECT
****************************************************************
****************************************************************
* Method GetCost Gets the COST of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCost″ .
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINE-COST TO LS-COST.
EXIT METHOD.
END METHOD ″GetCost″ .
EJECT
****************************************************************
****************************************************************
* Method SetType Sets the type of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetType″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE LS-TYPE TO WINE-TYPE.
EXIT METHOD.
END METHOD ″SetType″ .
EJECT
****************************************************************
****************************************************************
* Method SetCost Sets the COST of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetCost″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE LS-COST TO WINE-COST.
EXIT METHOD.
END METHOD ″SetCost″ .
EJECT
****************************************************************
****************************************************************
* Method GetStatus gets the inventory status of an item *
* that was ordered. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetStatus″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-STATUS-WORK PIC 9(5).
01 WS-STATUS-MOD PIC 9.
01 WS-RANDOM-WORK PIC 9V9(5).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-STATUS PIC X.
****************************************************************
* We aren′ t reading the inventory quantity from an *
* external file, so we need to generate our order status *
* in here. For starters, we′ ll assume that we have a 50% *
* chance of the item being in stock. *
****************************************************************
COMPUTE WS-RANDOM-WORK = FUNCTION RANDOM.
COMPUTE WS-STATUS-WORK = WS-RANDOM-WORK * 10000.
DIVIDE WS-STATUS-WORK BY 2 GIVING WS-STATUS-WORK
REMAINDER WS-STATUS-MOD.
****************************************************************
* If the generated number is even, set the status flag to *
* 0 which means out-of-stock; else set it to 1, or in-stock.*
****************************************************************
IF WS-STATUS-MOD = 0
THEN MOVE ″0″ TO LS-STATUS
ELSE
MOVE ″1″ TO LS-STATUS.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
****************************************************************
* Class FileRW : Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class FileRW contains the following methods: *
* XternOrder - Externalizes an order to a flat *
* file. *
* XReadOrder - Reads the order record from a flat *
* file and returns it to the invoker. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″ .
****************************************************************
* Define the WineOrder Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method XternOrder writes the order to a flat file. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″XternOrder″ .
DATA DIVISION.
FILE SECTION.
FD ORDERS EXTERNAL
RECORD CONTAINS 255.
01 ORDER-RECORD PIC X(255).
WORKING-STORAGE SECTION.
01 WS-STATUS-FLAG PIC XX.
01 WS-ORDER-RECORD.
05 WS-ORDER-NUMBER PIC X(5).
05 WS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 WS-ITEMS.
10 WS-ORDER-COUNT PIC S9(4).
10 WS-ORDER-ITEM OCCURS 1 TO 64
DEPENDING ON WS-ORDER-COUNT
INDEXED BY WS-INDEX.
15 WSO-TYPE PIC X(20).
15 WSO-COST PIC 999V99.
LINKAGE SECTION.
01 orderObj USAGE OBJECT REFERENCE WineOrder.
****************************************************************
* Open the flat file for output. *
****************************************************************
OPEN OUTPUT ORDERS.
MOVE SPACES TO WS-ORDER-RECORD.
****************************************************************
* Get all the instance data for the order object. *
****************************************************************
INVOKE orderObj ″GetInstanceData″
RETURNING WS-ORDER-RECORD.
****************************************************************
* Write the record. *
****************************************************************
WRITE ORDER-RECORD FROM WS-ORDER-RECORD.
****************************************************************
* Close the order file after writing the record to it. *
****************************************************************
CLOSE ORDERS.
EXIT METHOD.
END METHOD ″XternOrder″ .
EJECT
****************************************************************
****************************************************************
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ORDERS ASSIGN TO ORDERS
FILE STATUS IS WS-STATUS-FLAG
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD ORDERS EXTERNAL
RECORD CONTAINS 255.
01 ORDER-RECORD PIC X(255).
WORKING-STORAGE SECTION.
01 WS-STATUS-FLAG PIC XX.
01 WS-EOF-FLAG PIC X.
LINKAGE SECTION.
01 LS-ORDER PIC X(5).
01 LS-ORDER-RECORD.
05 LS-ORDER-NUMBER PIC X(5).
05 LS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 LS-ORDER-COUNT PIC S9(4).
05 LS-ORDER-ITEM OCCURS 1 TO 64
DEPENDING ON LS-ORDER-COUNT
INDEXED BY LS-INDEX.
10 LSO-TYPE PIC X(20).
10 LSO-COST PIC 999V99.
****************************************************************
* Open the flat file for input; initialize eof flag. *
****************************************************************
OPEN INPUT ORDERS.
MOVE LOW-VALUE TO WS-EOF-FLAG.
****************************************************************
* Read until the requested order is found on the file. *
****************************************************************
PERFORM UNTIL WS-EOF-FLAG = HIGH-VALUE
OR LS-ORDER-NUMBER = LS-ORDER
READ ORDERS INTO LS-ORDER-RECORD
AT END MOVE HIGH-VALUE TO WS-EOF-FLAG
NOT AT END
IF LS-ORDER-NUMBER = LS-ORDER
THEN CONTINUE
END-IF
END-READ
END-PERFORM.
EXIT METHOD.
END METHOD ″XReadOrder″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class FileRW. *
****************************************************************
END CLASS ″FileRW″ .
This appendix lists all the source modules for the fourth iteration of the Wine
Store Scenario.
****************************************************************
* *
* The client program of the wine application does the *
* following tasks: *
* - Instantiates the UserInterface obejct. *
* - If a status request: *
* -- instantiates an OldOrder object *
* -- invokes the UserInterface object to get the order *
* number *
* -- invokes the metaclass to report out-of-stock items *
* -- invokes the UserInterface object to display the *
* status of the out-of-stock items *
* -- invokes the metaclass object to get the count of *
* old orders checked *
* -- invokes the UserInterface object to display the *
* number of orders checked. *
* -- Frees the metaclass object *
* - If a request for a new order: *
* -- Tells the order object to process the user′ s request *
* and tells the userinterface object to get another *
* request until the user signals the end of the order. *
* If the request is an add or delete, sends the *
* appropriate message to the userinterface object for *
* the item cost and type, as required by the user′ s *
* processing request. *
* -- Tells the order object to compute the order cost. *
* -- Tells the order object to get the order number. *
* -- Tells the user interface object to write order cost. *
* -- Tells the order to describe itself. *
* -- Tells the order to write itself to the order file. *
* -- Frees the objects it instantiated. *
* - Frees the UserInterface object. *
* - Terminates. *
* *
****************************************************************
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″
CLASS OldOrder IS ″OldOrder″
CLASS Bottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
DATA DIVISION.
WORKING-STORAGE SECTION.
* OBJECTS:
01 orderObj USAGE OBJECT REFERENCE WineOrder.
01 oldOrderObj USAGE OBJECT REFERENCE OldOrder.
01 userObj USAGE OBJECT REFERENCE UserInterface.
01 bottleObj USAGE OBJECT REFERENCE Bottle.
01 fileObj USAGE OBJECT REFERENCE FileRW.
01 metaObj USAGE OBJECT REFERENCE METACLASS OldOrder.
* DATA ITEMS:
01 ACTION PIC X(10).
01 PROCESS PIC X(10).
01 STATUS-FLAG PIC X.
88 NO-STATUS-SELECTED VALUE LOW-VALUES.
88 STATUS-SELECTED VALUE HIGH-VALUES.
01 ITEM-TYPE PIC X(20).
01 ITEM-COST PIC 999V99.
01 MAX-ITEMS PIC 9(4) COMP VALUE 64.
01 WS-PARMS.
05 ITEM-COUNT PIC S9(8) COMP.
05 WS-FLAG PIC X.
88 SUCCESSFUL VALUE ″0″.
88 FAILURE VALUE ″1″.
01 WS-ORDER-RECORD.
05 WSO-ORDER-NUMBER PIC X(5).
05 WSO-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 WSO-ITEMS.
10 WSO-ORDER-COUNT PIC S9(4).
10 WSO-ORDER-ITEM OCCURS 1 TO 64
PROCEDURE DIVISION.
****************************************************************
* Initialized the status selected control flag for use *
* in later processing. *
****************************************************************
MOVE LOW-VALUES TO STATUS-FLAG.
****************************************************************
* Invoke the UserInterface class with the inherited somNew *
* method to instantiate a userinterface object. *
* somNew is inherited from SOMObject. *
****************************************************************
INVOKE UserInterface ″somNew″ RETURNING userObj.
****************************************************************
* Invoke the UserInterface class with the ReadProcess *
* method to obtain the process desired by the system user. *
****************************************************************
INVOKE userObj ″ReadProcess″ RETURNING PROCESS.
****************************************************************
* Use the process to control the path through this program. *
****************************************************************
PERFORM UNTIL PROCESS (1:4) = ″EXIT″
EVALUATE PROCESS (1:3)
WHEN ″STA″
PERFORM CHECK-OLD-ORDER THRU CHECK-EXIT
MOVE HIGH-VALUE TO STATUS-FLAG
WHEN ″NEW″
PERFORM CREATE-NEW-ORDER THRU CREATE-EXIT
WHEN OTHER
CONTINUE
END-EVALUATE
INVOKE userObj ″ReadProcess″ RETURNING PROCESS
END-PERFORM.
****************************************************************
* Check the status flag to see if we need to invoke *
* the countoldorders method in the metaclass. *
****************************************************************
IF STATUS-SELECTED
THEN PERFORM GET-COUNT THRU GET-EXIT.
****************************************************************
* Free the user interface object we created. *
****************************************************************
INVOKE userObj ″somFree″ .
****************************************************************
* We′ re outta here... *
****************************************************************
GOBACK.
****************************************************************
* Invoke the oldorder object to check the status of *
* ordered items. *
****************************************************************
INVOKE OldOrder ″CreateOldOrder″ USING ORDER-NUMBER
RETURNING META-PARMS.
****************************************************************
* Check to see if the order was found on the file; *
* send an error message if it wasn′ t. *
****************************************************************
IF LOST-FLAG = HIGH-VALUE
THEN INVOKE userObj ″WriteLost″ USING ORDER-NUMBER
GO TO CHECK-EXIT.
****************************************************************
* Invoke the userinterface object to write the status of *
* out-of-stock items. *
****************************************************************
INVOKE userObj ″WriteStatus″ USING OUT-ITEMS.
CHECK-EXIT.
EXIT.
EJECT
GET-COUNT.
****************************************************************
* Invoke the somGetClass method to get the handle of the *
* metaclass object. *
****************************************************************
INVOKE univObj ″somGetClass″ RETURNING metaObj.
****************************************************************
* Invoke the metaclass object to get the number of old *
* orders. *
****************************************************************
INVOKE metaObj ″CountOldOrders″ RETURNING OUT-ORDERS.
****************************************************************
* Invoke the userinterface object to write out the number *
* of old orders. *
****************************************************************
INVOKE userObj ″WriteOutCount″ USING OUT-ORDERS.
****************************************************************
* Free the metaclass object. *
****************************************************************
INVOKE metaObj ″somFree″ .
GET-EXIT.
EXIT.
****************************************************************
* Invoke the Order class with the inherited method somNew *
* to instantiate an order object. *
****************************************************************
INVOKE WineOrder ″somNew″ RETURNING orderObj.
****************************************************************
* Invoke the setordernumber and setorderdate methods to *
* set the order′ s date and number. *
****************************************************************
INVOKE orderObj ″SetOrderNumber″ USING ORDER-NUMBER.
INVOKE orderObj ″SetOrderDate″ USING ORDER-DATE.
****************************************************************
* Invoke the userinterface object with ReadAction method. *
****************************************************************
INVOKE userObj ″ReadAction″ RETURNING ACTION.
****************************************************************
* Loop until the user signals the end of the order. *
****************************************************************
PERFORM UNTIL ACTION (1:3) = ″END″
OR ITEM-COUNT = MAX-ITEMS
WHEN ″DEL″
* get the type and cost from the user interface
INVOKE userObj ″ReadType″ RETURNING ITEM-TYPE
INVOKE userObj ″ReadCost″ RETURNING ITEM-COST
WHEN OTHER
CONTINUE
END-EVALUATE
INVOKE userObj ″ReadAction″ RETURNING ACTION
END-PERFORM.
****************************************************************
* End of loop. *
****************************************************************
****************************************************************
* Close-out processing follows. *
****************************************************************
****************************************************************
* If no items were ordered, end the process here. *
****************************************************************
IF ITEM-COUNT = 0
****************************************************************
* Free the order object we created. *
****************************************************************
THEN INVOKE orderObj ″somFree″
GO TO CREATE-EXIT
END-IF.
****************************************************************
* Invoke the order object with the calculate cost method. *
****************************************************************
INVOKE orderObj ″CalculateCost″ RETURNING TOTAL-COST.
****************************************************************
* Invoke the order object with the getordernumber *
****************************************************************
* Invoke the userinterface object with writeoutput method. *
****************************************************************
INVOKE userObj ″WriteOutput″ USING TOTAL-COST
ORDER-NUMBER
ORDER-DATE.
****************************************************************
* Invoke the order object with the describeorder method. *
****************************************************************
INVOKE orderObj ″DescribeOrder″ RETURNING WS-ITEMS.
****************************************************************
* Invoke the userinterface object with writeoutput method. *
****************************************************************
INVOKE userObj ″WriteBottle″ USING WS-ITEMS.
****************************************************************
* Create a filereadwrite object with the inherited somNew *
* method. *
****************************************************************
INVOKE FileRW ″somNew″ RETURNING fileObj.
****************************************************************
* Invoke the file object with the xternorder method. *
****************************************************************
INVOKE fileObj ″XternOrder″ USING orderObj.
****************************************************************
* Free the filereadwrite object we created. *
****************************************************************
INVOKE fileObj ″somFree″ .
****************************************************************
* Free the order object we created. *
****************************************************************
INVOKE orderObj ″somFree″ .
CREATE-EXIT.
EXIT.
END PROGRAM ″Wine″ .
****************************************************************
* Class OldOrder : Inherits from WineOrder, and uses *
* the metaclass MetaOldOrder. *
****************************************************************
****************************************************************
* Class OldOrder contains the following methods: *
* CheckItems - Checks the status of ordered items. *
* somFree - Overridden method that invokes *
* destructor in parent class. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS OldOrder IS ″OldOrder″
CLASS MetaOldOrder IS ″MetaOldOrder″
CLASS WineOrder IS ″WineOrder″
CLASS WineBottle IS ″WineBottle″
CLASS FileRW IS ″FileRW″
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″ .
DATA DIVISION.
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method CheckItems checks to see if an item is in stock *
* or not. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″CheckItems″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 WINEORDER-LIST USAGE OBJECT REFERENCE SOMCollection.
01 WINEORDER-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
01 fileObj USAGE OBJECT REFERENCE FileRW.
01 WS-FLAG PIC X.
88 OUT-OF-STOCK VALUE ″0″.
88 IN-STOCK VALUE ″1″.
01 WS-TYPE PIC X(20).
01 WS-COST PIC 999V99.
01 WS-EV USAGE POINTER.
01 ITEM-COUNT PIC S9(8) COMP.
01 WS-ORDER-RECORD.
05 WSO-ORDER-NUMBER PIC X(5).
05 WSO-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 WSO-ITEMS.
10 WSO-ORDER-COUNT PIC S9(4).
10 WSO-ORDER-ITEM OCCURS 1 TO 64
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER-NUMBER PIC X(5).
01 LS-PARMS.
05 LS-LOST-FLAG PIC X.
05 LS-OUT-ITEMS.
10 LS-OUT-COUNT PIC S9(4).
10 LS-OUT-ITEM OCCURS 1 TO 64
DEPENDING ON LS-OUT-COUNT
INDEXED BY LS-INDEX.
15 LSO-TYPE PIC X(20).
15 LSO-COST PIC 999V99.
****************************************************************
* Create a filereadwrite object with the inherited somNew *
* method. *
****************************************************************
INVOKE FileRW ″somNew″ RETURNING fileObj.
****************************************************************
* Invoke the file object with the xreadorder method. *
****************************************************************
INVOKE fileObj ″XReadOrder″ USING LS-ORDER-NUMBER
RETURNING WS-ORDER-RECORD.
****************************************************************
* Check to see if the order was found on the file, and *
* exit with an error if it isn′ t. *
****************************************************************
IF LS-ORDER-NUMBER NOT = WSO-ORDER-NUMBER
THEN MOVE HIGH-VALUE TO LS-LOST-FLAG
EXIT METHOD
ELSE
MOVE LOW-VALUE TO LS-LOST-FLAG.
****************************************************************
* Free the filereadwrite object we created. *
****************************************************************
INVOKE fileObj ″somFree″ .
****************************************************************
* Set the instance data in the order object with the data *
* returned from the file object. *
****************************************************************
INVOKE self ″SetInstanceData″ USING WS-ORDER-RECORD.
****************************************************************
* Get the SOM environment variable, and the som collection *
* from the parent object so we can use them here. *
****************************************************************
* Get the count of the number of items in the collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
MOVE ZERO TO LS-OUT-COUNT.
SET LS-INDEX TO 1.
IF ITEM-COUNT > 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-STATUS
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-STATUS
END-PERFORM
END-IF.
EXIT METHOD.
****************************************************************
* Check the inventory status of the bottle by invoking its *
* GetStatus. If it′ s out of stock, move it to the table *
* and increment the out of stock counter. *
****************************************************************
CHECK-STATUS.
INVOKE CollectedBottle ″GetStatus″
RETURNING WS-FLAG.
IF OUT-OF-STOCK
THEN ADD 1 TO LS-OUT-COUNT
INVOKE CollectedBottle ″GetType″
RETURNING WS-TYPE
MOVE WS-TYPE TO LSO-TYPE (LS-INDEX)
INVOKE CollectedBottle ″GetCost″
RETURNING WS-COST
MOVE WS-COST TO LSO-COST (LS-INDEX)
SET LS-INDEX UP BY 1.
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somFree″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class OldOrder. *
****************************************************************
END CLASS ″OldOrder″ .
****************************************************************
* Class UserInterface: Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class UserInterface contains the following methods: *
* ReadAction - Gets the input command from the *
* system user. *
* ReadType - Gets the type of item from the *
* system user. *
* ReadCost - Gets the cost of item from the *
* system user. *
* WriteMessage - Displays a system status message to *
* the system user. *
* WriteOutput - Displays the cost of the order and *
* order to the system user. *
* WriteBottle - Displays the attributes of a bottle *
* collected in the order. *
* ReadProcess - Gets the processing request from the *
* system user. *
* ReadOrder - Gets the order number from the system *
* user. *
* WriteStatus - Displays the inventory status of *
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″ .
****************************************************************
* Define the UserInterface Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the instance data of the UserInterface Object. *
****************************************************************
01 USER-ACTION PIC X(10).
88 UA-ADD VALUE ″Add″ .
88 UA-DELETE VALUE ″Delete″ .
88 UA-END VALUE ″End″ .
88 UA-NEW VALUE ″New″ .
88 UA-STATUS VALUE ″Status″ .
88 UA-EXIT VALUE ″Exit″ .
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method ReadAction gets the system user′ s command to be *
* processed. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″ReadAction″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ACTION PIC X(10).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-TYPE PIC X(80).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
01 WS-COST-WORK PIC X(6).
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-FLAG PIC X.
IF LS-FLAG = ″0″
THEN DISPLAY USER-ACTION ″successful ″
ELSE
DISPLAY USER-ACTION ″failed ″
END-IF.
EXIT METHOD.
END METHOD ″WriteMessage″ .
EJECT
****************************************************************
****************************************************************
* Method WriteOutput displays the order number and cost *
* to the system user. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteOutput″ .
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TOTAL-COST PIC 9(7)V99.
01 LS-ORDER-NUMBER PIC 9(5).
01 LS-ORDER-DATE PIC X(8).
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ITEMS.
05 LS-ITEM-COUNT PIC S9(4).
05 LS-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ITEM-COUNT.
10 LS-TYPE PIC X(20).
10 LS-COST PIC 999V99.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-PROCESS PIC X(10).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EDIT-FLAG PIC X.
01 WS-ORDER PIC X(5).
01 WS-ORDER-9 PIC 9(5).
****************************************************************
EXIT METHOD.
END METHOD ″ReadOrder″ .
EJECT
****************************************************************
****************************************************************
* Method WriteStatus displays the inventory attributes and *
* out-of-stock items that are in the order. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″WriteStatus″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-OUT-ITEMS.
05 LS-OUT-COUNT PIC S9(4).
05 LS-OUT-ITEM OCCURS 1 to 64 TIMES
DEPENDING ON LS-OUT-COUNT.
10 LSO-TYPE PIC X(20).
10 LSO-COST PIC 999V99.
IF LS-OUT-COUNT > 0
THEN DISPLAY ″LIST OUT OF STOCK ITEMS: ″
INVOKE SELF ″WriteBottle″
USING LS-OUT-ITEMS
ELSE
DISPLAY ″ALL ITEMS IN STOCK!″ .
EXIT METHOD.
END METHOD ″WriteStatus″ .
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COUNT PIC S9(4) COMP.
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER-NUMBER PIC 9(5).
****************************************************************
* Class MetaOldOrder: Inherits from SOMClass *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class MetaOldOrder contains the following methods: *
* somDefaultInit - Initializes a MetaOldOrder object. *
* CreateOldOrder - Creates old order objects. *
* CountOldOrders - Counts old order objects. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS MetaOldOrder IS ″MetaOldOrder″
CLASS OldOrder IS ″OldOrder″
CLASS SOMClass IS ″SOMClass″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 STATUS-COUNT PIC S9(4) COMP.
EJECT
****************************************************************
****************************************************************
* Method somDefaultInit initializes the MetaOldOrder object.*
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somDefaultInit″ OVERRIDE.
PROCEDURE DIVISION.
****************************************************************
* Initialize the status counter. *
****************************************************************
MOVE ZERO TO STATUS-COUNT.
EXIT METHOD.
END METHOD ″somDefaultInit″ .
EJECT
****************************************************************
****************************************************************
* Method CreateOldOrder creates an oldorder object to be *
* counted. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″CreateOldOrder″ .
DATA DIVISION.
IF LS-ORDER-NUMBER > 0
THEN INVOKE SELF ″somNew″ RETURNING univObj
INVOKE univObj ″CheckItems″
USING LS-ORDER-NUMBER
RETURNING LS-CHECK-PARMS
ADD 1 TO STATUS-COUNT
END-IF.
EXIT METHOD.
END METHOD ″CreateOldOrder″ .
EJECT
****************************************************************
****************************************************************
* Method CountOldOrders returns the status-count field. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″CountOldOrders″ .
DATA DIVISION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-STATUS-COUNT PIC S9(4) COMP.
EXIT METHOD.
END METHOD ″CountOldOrders″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class MetaOldOrder. *
****************************************************************
END CLASS MetaOldOrder.
****************************************************************
* Class FileRW : Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class FileRW contains the following methods: *
* XternOrder - Externalizes an order to a flat *
* file. *
* XReadOrder - Reads the order record from a flat *
* file and returns it to the invoker. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS WineOrder IS ″WineOrder″ .
****************************************************************
* Define the WineOrder Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method XternOrder writes the order to a flat file. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″XternOrder″ .
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ORDERS ASSIGN TO ORDERS
FILE STATUS IS WS-STATUS-FLAG
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD ORDERS EXTERNAL
RECORD CONTAINS 255.
WORKING-STORAGE SECTION.
01 WS-STATUS-FLAG PIC XX.
01 WS-ORDER-RECORD.
05 WS-ORDER-NUMBER PIC X(5).
05 WS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 WS-ITEMS.
10 WS-ORDER-COUNT PIC S9(4).
10 WS-ORDER-ITEM OCCURS 1 TO 64
DEPENDING ON WS-ORDER-COUNT
INDEXED BY WS-INDEX.
15 WSO-TYPE PIC X(20).
15 WSO-COST PIC 999V99.
LINKAGE SECTION.
01 orderObj USAGE OBJECT REFERENCE WineOrder.
****************************************************************
* Open the flat file for output. *
****************************************************************
OPEN OUTPUT ORDERS.
MOVE SPACES TO WS-ORDER-RECORD.
****************************************************************
* Get all the instance data for the order object. *
****************************************************************
INVOKE orderObj ″GetInstanceData″
RETURNING WS-ORDER-RECORD.
****************************************************************
* Write the record. *
****************************************************************
WRITE ORDER-RECORD FROM WS-ORDER-RECORD.
****************************************************************
* Close the order file after writing the record to it. *
****************************************************************
CLOSE ORDERS.
EXIT METHOD.
END METHOD ″XternOrder″ .
EJECT
****************************************************************
****************************************************************
* Method XReadOrder reads the order from a flat file. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″XReadOrder″ .
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ORDERS ASSIGN TO ORDERS
FILE STATUS IS WS-STATUS-FLAG
ORGANIZATION IS LINE SEQUENTIAL.
WORKING-STORAGE SECTION.
01 WS-STATUS-FLAG PIC XX.
01 WS-EOF-FLAG PIC X.
LINKAGE SECTION.
01 LS-ORDER PIC X(5).
01 LS-ORDER-RECORD.
05 LS-ORDER-NUMBER PIC X(5).
05 LS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 LS-ORDER-COUNT PIC S9(4).
05 LS-ORDER-ITEM OCCURS 1 TO 64
DEPENDING ON LS-ORDER-COUNT
INDEXED BY LS-INDEX.
10 LSO-TYPE PIC X(20).
10 LSO-COST PIC 999V99.
****************************************************************
* Open the flat file for input; initialize eof flag. *
****************************************************************
OPEN INPUT ORDERS.
MOVE LOW-VALUE TO WS-EOF-FLAG.
****************************************************************
* Read until the requested order is found on the file. *
****************************************************************
PERFORM UNTIL WS-EOF-FLAG = HIGH-VALUE
OR LS-ORDER-NUMBER = LS-ORDER
READ ORDERS INTO LS-ORDER-RECORD
AT END MOVE HIGH-VALUE TO WS-EOF-FLAG
NOT AT END
IF LS-ORDER-NUMBER = LS-ORDER
THEN CONTINUE
END-IF
END-READ
END-PERFORM.
****************************************************************
* Close the order file after reading the record. *
****************************************************************
CLOSE ORDERS.
EXIT METHOD.
END METHOD ″XReadOrder″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class FileRW. *
****************************************************************
* Class WineBottle : Inherits from somf_MCollectible *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class WineBottle contains the following methods: *
* somfIsEqual - Provides SOM a method to see if two *
* objects are equivalent. *
* SetCost - Sets the cost of a WineBottle object *
* based on a given object reference. *
* SetType - Sets the type of a WineBottle object *
* based on a given object reference. *
* GetCost - Retrieves the cost of a WineBottle *
* object based on a given object *
* reference. *
* GetType - Retrieves the type of a WineBottle *
* object based on a given object *
* reference. *
* GetStatus - Retrieves the inventory status of *
* a wine bottle based on a given obect *
* reference. *
****************************************************************
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS WineBottle IS ″WineBottle″
CLASS somf-MCollectible IS ″somf_MCollectible″ .
****************************************************************
* Define the WineBottle Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the instance data of the WineBottle Object. *
****************************************************************
01 WINEBOTTLE-OBJECT.
05 WINE-TYPE PIC X(20).
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* Method somfIsEqual provides SOM a method to see if two *
* bottle objects are equivalent. In our case, if their *
* types and costs are the same, we consider them equal. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somfIsEqual″ OVERRIDE.
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 ITEMTYPE PIC X(20).
01 ITEMCOST PIC 999V99.
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
01 theBottle Usage Object Reference WineBottle.
01 theEqualFlag PIC X.
****************************************************************
* Get the type and cost of the bottle object *
****************************************************************
INVOKE theBottle ″GetType″ RETURNING ITEMTYPE.
INVOKE theBottle ″GetCost″ RETURNING ITEMCOST.
****************************************************************
* Get those just obtained to the attributes of this *
* instance. If they are equal, set the equality flag *
* to a binary 1, else set it to a low-value. *
****************************************************************
IF (WINE-TYPE = ITEMTYPE) AND
(WINE-COST = ITEMCOST)
THEN MOVE HIGH-VALUE TO theEqualFlag
ELSE
MOVE LOW-VALUE TO theEqualFlag.
EXIT METHOD.
END METHOD ″somfIsEqual″ .
EJECT
****************************************************************
****************************************************************
* Method GetType Gets the type of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetType″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINE-TYPE TO LS-TYPE.
EXIT METHOD.
END METHOD ″GetType″ .
EJECT
****************************************************************
****************************************************************
* Method GetCost Gets the COST of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetCost″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINE-COST TO LS-COST.
EXIT METHOD.
END METHOD ″GetCost″ .
EJECT
****************************************************************
****************************************************************
* Method SetType Sets the type of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetType″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-TYPE PIC X(20).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE LS-TYPE TO WINE-TYPE.
EXIT METHOD.
END METHOD ″SetType″ .
EJECT
****************************************************************
****************************************************************
* Method SetCost Sets the COST of a WineBottle based on the *
* object reference of the WineBottle. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetCost″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 999V99.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE LS-COST TO WINE-COST.
EXIT METHOD.
END METHOD ″SetCost″ .
EJECT
****************************************************************
****************************************************************
* Method GetStatus gets the inventory status of an item *
* that was ordered. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetStatus″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-STATUS-WORK PIC 9(5).
01 WS-STATUS-MOD PIC 9.
01 WS-RANDOM-WORK PIC 9V9(5).
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-STATUS PIC X.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
EXIT METHOD.
END METHOD ″GetStatus″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class WineBottle. *
****************************************************************
END CLASS ″WineBottle″ .
****************************************************************
* Class WineOrder : Inherits from SOMObject *
* in the SOM Class Library. *
****************************************************************
****************************************************************
* Class WineOrder contains the following methods: *
* somDefaultInit - Initializes a WineOrder object. *
* somFree - Frees bottles, collection, and order. *
* SetOrderNumber - Sets the number of a WineOrder object *
* based on a given object reference. *
* SetOrderDate - Sets the date of a WineOrder object *
* based on a given object reference. *
* AddBottle - Adds a bottle object to the order *
* RemoveBottle - Removes a bottle object from the *
* order. *
* CalculateCost - Computes the cost of the bottle *
* objects in the order. *
ENVIRONMENT DIVISION.
****************************************************************
* Define which classes will be used by the methods in *
* this class. *
****************************************************************
CONFIGURATION SECTION.
REPOSITORY.
CLASS SOMObject IS ″SOMObject″
CLASS SOMCollection IS ″somf_TSet″
CLASS SOMIterator IS ″somf_TSetIterator″
CLASS WineBottle IS ″WineBottle″ .
****************************************************************
* Define the WineOrder Object. *
****************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-EV USAGE POINTER.
****************************************************************
* Define the instance data of the WineOrder Object. *
****************************************************************
01 WINEORDER-OBJECT.
05 WINEORDER-NUMBER PIC X(5).
05 WINEORDER-DATE PIC X(8).
05 WINEORDER-LIST USAGE OBJECT REFERENCE SOMCollection.
****************************************************************
* Define an iterator for use on the wineorder-list. *
****************************************************************
01 WINEORDER-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
EJECT
PROCEDURE DIVISION.
****************************************************************
****************************************************************
* The overridden method somDefaultInit initializes the *
DATA DIVISION.
PROCEDURE DIVISION.
****************************************************************
* Initialize the SOM global environment variable. *
****************************************************************
CALL ″somGetGlobalEnvironment″ RETURNING WS-EV.
****************************************************************
* Now initialize an empty collection for us to add bottles *
* into with the addBottle method. *
****************************************************************
INVOKE SOMCollection ″somNew″
RETURNING WINEORDER-LIST.
****************************************************************
* Instantiate an iterator object and associate it with the *
* collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCreateIterator″
USING BY VALUE WS-EV
RETURNING WINEORDER-ITERATOR.
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somDefaultInit″ .
EJECT
****************************************************************
****************************************************************
* The overridden method somFree destroys the bottle *
* objects created, the collection object, and the order *
* object. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″somFree″ OVERRIDE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 ITEM-COUNT PIC S9(8) COMP.
PROCEDURE DIVISION.
****************************************************************
* Get the collected objects. *
****************************************************************
INVOKE WINEORDER-LIST ″somfDeleteAll″
USING BY VALUE WS-EV.
****************************************************************
****************************************************************
* Free thyself...Use SUPER so we don′ t recurse back into *
* this method. *
****************************************************************
INVOKE SUPER ″somFree″ .
****************************************************************
* EXIT and END the method. *
****************************************************************
EXIT METHOD.
END METHOD ″somFree″ .
EJECT
****************************************************************
****************************************************************
* Method GetOrderNumber gets the number of WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderNumber″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERNUMBER PIC X(5).
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINEORDER-NUMBER TO LS-ORDERNUMBER.
EXIT METHOD.
END METHOD ″GetOrderNumber″ .
EJECT
****************************************************************
****************************************************************
* Method GetOrderDate gets the date of a WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetOrderDate″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
MOVE WINEORDER-DATE TO LS-ORDERDATE.
EXIT METHOD.
END METHOD ″GetOrderDate″ .
EJECT
****************************************************************
****************************************************************
* Method SetOrderNumber sets the number of WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetOrderNumber″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERNUMBER PIC X(5).
****************************************************************
* Move data from the LINKAGE SECTION. *
****************************************************************
MOVE LS-ORDERNUMBER TO WINEORDER-NUMBER.
EXIT METHOD.
END METHOD ″SetOrderNumber″ .
EJECT
****************************************************************
****************************************************************
* Method SetOrderDate sets the date of a WineOrder based *
* on the object reference of the WineOrder. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetOrderDate″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDERDATE PIC X(8).
EXIT METHOD.
END METHOD ″SetOrderDate″ .
EJECT
****************************************************************
****************************************************************
* Method DescribeOrder describes the order contents. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″DescribeOrder″ .
DATA DIVISION.
LOCAL-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 WS-TYPE PIC X(20).
01 WS-COST PIC 999V99.
01 ITEM-COUNT PIC S9(8) COMP.
LINKAGE SECTION.
01 LS-ITEMS.
05 LS-ITEM-COUNT PIC S9(4).
05 LS-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ITEM-COUNT
INDEXED BY LS-INDEX.
10 LS-TYPE PIC X(20).
10 LS-COST PIC 999V99.
****************************************************************
* Get the count of the number of items in the collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING ITEM-COUNT.
MOVE ITEM-COUNT TO LS-ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT > 0
THEN SET LS-INDEX TO 1
INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-TYPE-N-COST
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
****************************************************************
* Exit and end the method. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the gettype and getcost methods on the bottle *
* object and move the returned attributes to the table. *
****************************************************************
GET-TYPE-N-COST.
INVOKE CollectedBottle ″GetType″ RETURNING WS-TYPE.
MOVE WS-TYPE TO LS-TYPE (LS-INDEX).
INVOKE CollectedBottle ″GetCost″ RETURNING WS-COST.
MOVE WS-COST TO LS-COST (LS-INDEX).
DATA DIVISION.
WORKING-STORAGE SECTION.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 ITEM-COUNT PIC S9(8) COMP.
01 WS-COST PIC 999V99.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-COST PIC 9(7)V99.
****************************************************************
* Initialize the accumulator for the total cost. *
****************************************************************
MOVE ZERO TO LS-COST.
****************************************************************
* Get the count of the number of items in the collection. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING ITEM-COUNT.
****************************************************************
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM ITEM-COUNT TIMES
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM GET-COST
END-PERFORM
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the getcost method on the bottle object and *
* accumulate the cost. *
****************************************************************
GET-COST.
INVOKE CollectedBottle ″GetCost″ RETURNING WS-COST.
ADD WS-COST TO LS-COST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-BEFORE-COUNT PIC S9(8) COMP.
01 WS-AFTER-COUNT PIC S9(8) COMP.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 theEqualFlag PIC X.
01 ITEM-FOUND-FLAG PIC X.
01 ITEM-COUNT PIC S9(8) COMP.
01 LOOP-COUNT PIC S9(8) COMP.
****************************************************************
* Define the linkage attributes. *
****************************************************************
****************************************************************
* Get the count of items before adding the object. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-BEFORE-COUNT.
MOVE WS-BEFORE-COUNT TO ITEM-COUNT.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT NOT = 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM VARYING LOOP-COUNT
FROM 1 BY 1
UNTIL LOOP-COUNT > ITEM-COUNT
OR ITEM-FOUND-FLAG = HIGH-VALUE
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL
END-PERFORM
END-IF.
****************************************************************
* Add the bottle to the collection if it hasn′ t been *
* added before. *
****************************************************************
IF ITEM-FOUND-FLAG = LOW-VALUE
THEN INVOKE WINEORDER-LIST ″somfAdd″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE.
****************************************************************
* Get the count of items after adding the object. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
****************************************************************
* If the counts are the same the add failed. *
****************************************************************
IF WS-BEFORE-COUNT = WS-AFTER-COUNT
THEN MOVE ″1″ TO LS-FLAG
ELSE
MOVE ″0″ TO LS-FLAG
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
****************************************************************
* Invoke the somfIsEqual method in the bottle object to *
* see if the objects are equal. Set a flag if they are. *
****************************************************************
CHECK-EQUAL.
INVOKE CollectedBottle ″somfIsEqual″
USING BY VALUE WS-EV
BY VALUE LS-BOTTLE
RETURNING theEqualFlag.
IF theEqualFlag = HIGH-VALUE
THEN MOVE HIGH-VALUE TO ITEM-FOUND-FLAG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-BEFORE-COUNT PIC S9(8) COMP.
01 WS-AFTER-COUNT PIC S9(8) COMP.
01 CollectedBottle USAGE OBJECT REFERENCE WineBottle.
01 theEqualFlag PIC X.
01 ITEM-COUNT PIC S9(8) COMP.
01 LOOP-COUNT PIC S9(8) COMP.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-BOTTLE USAGE OBJECT REFERENCE WineBottle.
01 LS-PARMS.
05 LS-ITEM-COUNT PIC S9(8) COMP.
05 LS-FLAG PIC X.
****************************************************************
* Get the first one in the collection. *
****************************************************************
IF ITEM-COUNT NOT = 0
THEN INVOKE WINEORDER-ITERATOR ″somfFirst″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL-N-REMOVE
END-IF.
****************************************************************
* Get the rest... *
****************************************************************
SUBTRACT 1 FROM ITEM-COUNT.
IF ITEM-COUNT > 0
THEN PERFORM VARYING LOOP-COUNT
FROM 1 BY 1
UNTIL LOOP-COUNT > ITEM-COUNT
OR theEqualFlag = HIGH-VALUE
INVOKE WINEORDER-ITERATOR ″somfNext″
USING BY VALUE WS-EV
RETURNING CollectedBottle
PERFORM CHECK-EQUAL-N-REMOVE
END-PERFORM
END-IF.
****************************************************************
* Get the count of items after the delete. *
****************************************************************
INVOKE WINEORDER-LIST ″somfCount″
USING BY VALUE WS-EV
RETURNING WS-AFTER-COUNT.
MOVE WS-AFTER-COUNT TO LS-ITEM-COUNT.
****************************************************************
* If the counts are the same the delete failed. *
****************************************************************
IF WS-BEFORE-COUNT = WS-AFTER-COUNT
THEN MOVE ″1″ TO LS-FLAG
ELSE
MOVE ″0″ TO LS-FLAG
END-IF.
****************************************************************
* EXIT the method and return. *
****************************************************************
EXIT METHOD.
CHECK-EQUAL-N-REMOVE.
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-EV USAGE POINTER.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
SET LS-EV TO WS-EV.
EXIT METHOD.
END METHOD ″GetEV″ .
EJECT
****************************************************************
****************************************************************
* Method GetList gets the wineorder list collection. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetList″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-LIST USAGE OBJECT REFERENCE SOMCollection.
EXIT METHOD.
END METHOD ″GetList″ .
EJECT
****************************************************************
****************************************************************
* Method GetIterator gets the wineorder list iterator. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetIterator″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ITERATOR USAGE OBJECT REFERENCE SOMIterator.
****************************************************************
* Move data to the LINKAGE SECTION. *
****************************************************************
SET LS-ITERATOR TO WINEORDER-ITERATOR.
EXIT METHOD.
END METHOD ″GetIterator″ .
EJECT
****************************************************************
****************************************************************
* Method SetInstanceData sets all the attributes of an *
* order object from data passed in the linkage section. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″SetInstanceData″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PARMS.
05 ITEM-COUNT PIC S9(8) COMP.
05 WS-FLAG PIC X.
88 SUCCESSFUL VALUE ″0″.
88 FAILURE VALUE ″1″.
01 bottleObj USAGE OBJECT REFERENCE WineBottle.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER.
05 LS-ORDER-NUMBER PIC X(5).
05 LS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
****************************************************************
* Move in the easy stuff... *
****************************************************************
INVOKE self ″SetOrderNumber″ USING LS-ORDER-NUMBER.
INVOKE self ″SetOrderDate″ USING LS-ORDER-DATE.
****************************************************************
* And now the tricky stuff... *
****************************************************************
PERFORM VARYING LS-INDEX FROM 1 BY 1
UNTIL LS-INDEX > LS-ORDER-COUNT
INVOKE WineBottle ″somNew″ RETURNING bottleObj
INVOKE bottleObj ″SetType″ USING LSO-TYPE (LS-INDEX)
INVOKE bottleObj ″SetCost″ USING LSO-COST (LS-INDEX)
INVOKE self ″AddBottle″ USING bottleObj
RETURNING WS-PARMS
END-PERFORM.
EXIT METHOD.
END METHOD ″SetInstanceData″ .
EJECT
****************************************************************
****************************************************************
* Method GetInstanceData retrieves all the attributes of an *
* order object and places them in the linkage section. *
****************************************************************
IDENTIFICATION DIVISION.
METHOD-ID. ″GetInstanceData″ .
DATA DIVISION.
WORKING-STORAGE SECTION.
****************************************************************
* Define the linkage attributes. *
****************************************************************
LINKAGE SECTION.
01 LS-ORDER.
05 LS-ORDER-NUMBER PIC X(5).
05 LS-ORDER-DATE PIC X(8).
05 FILLER PIC XXX.
05 LS-ITEMS.
10 LS-ORDER-COUNT PIC S9(4).
10 LS-ORDER-ITEM OCCURS 1 TO 64 TIMES
DEPENDING ON LS-ORDER-COUNT
INDEXED BY LS-INDEX.
15 LSO-TYPE PIC X(20).
15 LSO-COST PIC 999V99.
EXIT METHOD.
END METHOD ″GetInstanceData″ .
SKIP3
SKIP3
****************************************************************
* End object definition and class WineOrder. *
****************************************************************
END CLASS ″WineOrder″ .
IBM is grateful to the American National Standards ANSI (American National Standards Institute). An
Institute (ANSI) for permission to reprint its definitions organization consisting of producers, consumers, and
from the following publications: general interest groups, that establishes the
•
procedures by which accredited organizations create
American National Standard Programming
and maintain voluntary industry standards in the
Language COBOL, ANSI X3.23-1985 (Copyright
United States.
1985 American National Standards Institute, Inc.),
which was prepared by Technical Committee
* argument. An identifier, a literal, an arithmetic
X3J4, which had the task of revising American
expression, or a function-identifier that specifies a
National Standard COBOL, X3.23-1974.
value to be used in the evaluation of a function.
• American National Dictionary for Information
Processing Systems (Copyright 1982 by the * arithmetic expression. An identifier of a numeric
Computer and Business Equipment Manufacturers elementary item, a numeric literal, such identifiers
Association). and literals separated by arithmetic operators, two
arithmetic expressions separated by an arithmetic
American National Standard definitions are preceded operator, or an arithmetic expression enclosed in
by an asterisk (*). parentheses.
* alphanumeric character. Any character in the * ascending key. A key upon the values of which
computer’s character set. data is ordered, starting with the lowest value of the
key up to the highest value of the key, in accordance
alphanumeric-edited character. A character within an with the rules for comparing data items.
alphanumeric character-string that contains at least
one B, 0 (zero), or / (slash). ASCII. American National Standard Code for
Information Interchange. The standard code, using a
* alphanumeric function. A function whose value is coded character set consisting of 7-bit coded
composed of a string of one or more characters from characters (8 bits including parity check), used for
the computer′s character set. information interchange between data processing
systems, data communication systems, and
* COBOL character set. The complete COBOL * common program. A program which, despite being
character set consists of the characters listed below: directly contained within another program, may be
Character Meaning called from any program directly or indirectly
0,1...,9 digit contained in that other program.
A,B,...,Z uppercase letter
* compile. (1) To translate a program expressed in a
a,b,...,z lowercase letter
high-level language into a program expressed in an
• space
intermediate language, assembly language, or a
+ plus sign
computer language. (2) To prepare a machine
− minus sign (hyphen)
language program from a computer program written
* asterisk
in another programming language by making use of
/ slant (virgule, slash)
the overall logic structure of the program, or
= equal sign
generating more than one computer instruction for
$ currency sign
each symbolic statement, or both, as well as
, comma (decimal point)
performing the function of an assembler.
; semicolon
. period (decimal point, full stop)
* compile time. The time at which a COBOL source
″ quotation mark
program is translated, by a COBOL compiler, to a
( left parenthesis
COBOL object program.
Glossary 329
compiler. A program that translates a program * conditional variable. A data item one or more
written in a higher level language into a machine values of which has a condition-name assigned to it.
language object program.
* condition-name. A user-defined word that assigns a
compiler directing statement. A statement, beginning name to a subset of values that a conditional variable
with a compiler directing verb, that causes the may assume; or a user-defined word assigned to a
compiler to take a specific action during compilation. status of an implementor defined switch or device.
When ‘condition-name’ is used in the general formats,
compiler directing statement. A statement that it represents a unique data item reference consisting
specifies actions to be taken by the compiler during of a syntactically correct combination of a
processing of a COBOL source program. Compiler ‘condition-name’, together with qualifiers and
directives are contained in the COBOL source subscripts, as required for uniqueness of reference.
program. Thus, you can specify different suboptions
of the directive within the source program by using * condition-name condition. The proposition, for
multiple compiler directive statements in the which a truth value can be determined, that the value
program. of a conditional variable is a member of the set of
values attributed to a condition-name associated with
* complex condition. A condition in which one or the conditional variable.
more logical operators act upon one or more
conditions. (See also “negated simple condition,” * CONFIGURATION SECTION. A section of the
“combined condition,” and “negated combined ENVIRONMENT DIVISION that describes overall
condition.”) specifications of source and object programs and
class definitions.
* computer-name. A system-name that identifies the
computer upon which the program is to be compiled CONSOLE. A COBOL environment-name associated
or run. with the operator console.
condition. An exception that has been enabled, or * contiguous items. Items that are described by
recognized, by &cel. and thus is eligible to activate consecutive entries in the Data Division, and that
user and language condition handlers. Any alteration bear a definite hierarchic relationship to each other.
to the normal programmed flow of an application.
Conditions can be detected by the hardware/operating CORBA. The Common Object Request Broker
system and results in an interrupt. They can also be Architecture established by the Object Management
detected by language-specific generated code or Group. IBM′ s Interface Definition Language used to
language library code. describe the interface for SOM classes is fully
compliant with CORBA standards.
* condition. A status of a program at run time for
which a truth value can be determined. Where the * counter. A data item used for storing numbers or
term ‘condition’ (condition-1, condition-2,...) appears number representations in a manner that permits
in these language specifications in or in reference to these numbers to be increased or decreased by the
‘condition’ (condition-1, condition-2,...) of a general value of another number, or to be changed or reset to
format, it is a conditional expression consisting of zero or to an arbitrary positive or negative value.
either a simple condition optionally parenthesized, or
a combined condition consisting of the syntactically cross-reference listing. The portion of the compiler
correct combination of simple conditions, logical listing that contains information on where files, fields,
operators, and parentheses, for which a truth value and indicators are defined, referenced, and modified
can be determined. in a program.
* conditional expression. A simple condition or a currency sign. The character ‘$’ of the COBOL
complex condition specified in an EVALUATE, IF, character set or that character defined by the
PERFORM, or SEARCH statement. (See also “simple CURRENCY compiler option. If the NOCURRENCY
condition” and “complex condition.”) compiler option is in effect, the currency sign is
defined as the character ‘$’.
* conditional phrase. A conditional phrase specifies
the action to be taken upon determination of the truth currency symbol. The character defined by the
value of a condition resulting from the execution of a CURRENCY compiler option or by the CURRENCY
conditional statement. SIGN clause in the SPECIAL-NAMES paragraph. If the
NOCURRENCY compiler option is in effect for a
* conditional statement. A statement specifying that COBOL source program and the CURRENCY SIGN
the truth value of a condition is to be determined and clause is also not present in the source program, the
that the subsequent action of the object program is currency symbol is identical to the currency sign.
dependent on this truth value.
* declaratives. A set of one or more special purpose do-until. In structured programming, a do-until loop
sections, written at the beginning of the Procedure will be executed at least once, and until a given
Division, the first of which is preceded by the key condition is true. In COBOL, a TEST AFTER phrase
word DECLARATIVES and the last of which is followed used with the PERFORM statement functions in the
by the key words END DECLARATIVES. A declarative same way.
is composed of a section header, followed by a USE
compiler directing sentence, followed by a set of zero, do-while. In structured programming, a do-while loop
one, or more associated paragraphs. will be executed if, and while, a given condition is
Glossary 331
true. In COBOL, a TEST BEFORE phrase used with * elementary item. A data item that is described as
the PERFORM statement functions in the same way. not being further logically subdivided.
Double-Byte Character Set (DBCS). A set of enclave. When running under the &cel. product, an
characters in which each character is represented by enclave is analogous to a run unit. An enclave can
two bytes. Languages such as Japanese, Chinese, create other enclaves on MVS and CMS by a LINK, on
and Korean, which contain more symbols than can be CMS by CMSCALL, and the use of the system ()
represented by 256 code points, require Double-Byte function of C.
Character Sets. Because each character requires two
bytes, entering, displaying, and printing DBCS *end class header. A combination of words, followed
characters requires hardware and supporting software by a separator period, that indicates the end of a
that are DBCS-capable. COBOL class definition. The end class header is:
END CLASS class-name.
* dynamic access. An access mode in which specific
logical records can be obtained from or placed into a *end method header. A combination of words,
mass storage file in a nonsequential manner and followed by a separator period, that indicates the end
obtained from a file in a sequential manner during the of a COBOL method definition. The end method
scope of the same OPEN statement. header is:
edited data item. A data item that has been modified * environment clause. A clause that appears as part
by suppressing zeroes and/or inserting editing of an ENVIRONMENT DIVISION entry.
characters.
ENVIRONMENT DIVISION. One of the four main
* editing character. A single character or a fixed component parts of a COBOL program, class
two-character combination belonging to the following definition, or method definition. The ENVIRONMENT
set: DIVISION describes the computers upon which the
Character Meaning source program is compiled and those on which the
• space object program is executed, and provides a linkage
0 zero between the logical concept of files and their records,
+ plus and the physical aspects of the devices on which files
− minus are stored.
CR credit
DB debit environment-name. A name, specified by IBM, that
Z zero suppress identifies system logical units, printer and card punch
* check protect control characters, report codes, and/or program
$ currency sign switches. When an environment-name is associated
, comma (decimal point) with a mnemonic-name in the ENVIRONMENT
. period (decimal point) DIVISION, the mnemonic-name may then be
/ slant (virgule, slash) substituted in any format in which such substitution is
valid.
element (text element). One logical unit of a string of
text, such as the description of a single data item or environment variable. Any of a number of variables
verb, preceded by a unique code identifying the that describe the way an operating system is going to
element type. run and the devices it is going to recognize.
* external data record. A logical record which is * file control entry. A SELECT clause and all its
described in one or more programs of a run unit and subordinate clauses which declare the relevant
whose constituent data items may be referenced from physical attributes of a file.
any program in which they are described.
* file description entry. An entry in the File Section
external decimal item. A format for representing of the DATA DIVISION that is composed of the level
numbers in which the digit is contained in bits 4 indicator FD, followed by a file-name, and then
through 7 and the sign is contained in bits 0 through 3 followed by a set of file clauses as required.
of the rightmost byte. Bits 0 through 3 of all other
bytes contain 1’s (hex F). For example, the decimal * file-name. A user-defined word that names a file
value of +123 is represented as 1111 0001 1111 0010 connector described in a file description entry or a
1111 0011. (Also know as “zoned decimal item.”) sort-merge file description entry within the File
Section of the DATA DIVISION.
* external file connector. A file connector which is
accessible to one or more object programs in the run * file organization. The permanent logical file
unit. structure established at the time that a file is created.
external floating-point item. A format for *file position indicator. A conceptual entity that
representing numbers in which a real number is contains the value of the current key within the key of
represented by a pair of distinct numerals. In a reference for an indexed file, or the record number of
floating-point representation, the real number is the the current record for a sequential file, or the relative
product of the fixed-point part (the first numeral), and record number of the current record for a relative file,
a value obtained by raising the implicit floating-point or indicates that no next logical record exists, or that
base to a power denoted by the exponent (the second an optional input file is not present, or that the at end
numeral). condition already exists, or that no valid next record
has been established.
Glossary 333
* File Section. The section of the DATA DIVISION
that contains file description entries and sort-merge G
file description entries together with their associated
* global name. A name which is declared in only one
record descriptions.
program but which may be referenced from that
file system. The collection of files and file program and from any program contained within that
management structures on a physical or logical mass program. Condition-names, data-names, file-names,
storage device, such as a diskette or minidisk. record-names, report-names, and some special
registers may be global names.
* fixed file attributes. Information about a file which
is established when a file is created and cannot * group item. A data item that is composed of
subsequently be changed during the existence of the subordinate data items.
file. These attributes include the organization of the
file (sequential, relative, or indexed), the prime record
key, the alternate record keys, the code set, the
H
minimum and maximum record size, the record type
header label. (1) A file label or data set label that
(fixed or variable), the collating sequence of the keys
precedes the data records on a unit of recording
for indexed files, the blocking factor, the padding
media. (2) Synonym for beginning-of-file label.
character, and the record delimiter.
* high order end. The leftmost character of a string
* fixed length record. A record associated with a file
of characters.
whose file description or sort-merge description entry
requires that all records contain the same number of
character positions. I
fixed-point number. A numeric data item defined IBM COBOL extension. Certain COBOL syntax and
with a PICTURE clause that specifies the location of semantics supported by IBM compilers in addition to
an optional sign, the number of digits it contains, and those described in ANSI Standard.
the location of an optional decimal point. The format
may be either binary, packed decimal, or external IDENTIFICATION DIVISION. One of the four main
decimal. component parts of a COBOL program, class
definition, or method definition. The IDENTIFICATION
floating-point number. A numeric data item DIVISION identifies the program name, class name, or
containing a fraction and an exponent. Its value is method name. The IDENTIFICATION DIVISION may
obtained by multiplying the fraction by the base of the include the following documentation: author name,
numeric data item raised to the power specified by installation, or date.
the exponent.
* identifier. A syntactically correct combination of
* format. A specific arrangement of a set of data. character-strings and separators that names a data
item. When referencing a data item that is not a
* function. A temporary data item whose value is function, an identifier consists of a data-name,
determined at the time the function is referenced together with its qualifiers, subscripts, and
during the execution of a statement. reference-modifier, as required for uniqueness of
reference. When referencing a data item which is a
* function-identifier. A syntactically correct
function, a function-identifier is used.
combination of character-strings and separators that
references a function. The data item represented by IGZCBSN. The &cobol. bootstrap routine. It must be
a function is uniquely identified by a function-name link-edited with any module that contains a &cobol.
with its arguments, if any. A function-identifier may program.
include a reference-modifier. A function-identifier that
references an alphanumeric function may be specified * imperative statement. A statement that either
anywhere in the general formats that an identifier begins with an imperative verb and specifies an
may be specified, subject to certain restrictions. A unconditional action to be taken or is a conditional
function-identifier that references an integer or statement that is delimited by its explicit scope
numeric function may be referenced anywhere in the terminator (delimited scope statement). A n
general formats that an arithmetic expression may be imperative statement may consist of a sequence of
specified. imperative statements.
function-name. A word that names the mechanism * implicit scope terminator. A separator period which
whose invocation, along with required arguments, terminates the scope of any preceding unterminated
determines the value of a function. statement, or a phrase of a statement which by its
occurrence indicates the end of the scope of any
statement contained within the preceding phrase.
* index data item. A data item in which the values * input procedure. A set of statements, to which
associated with an index-name can be stored in a control is given during the execution of a SORT
form specified by the implementor. statement, for the purpose of controlling the release
of specified records to be sorted.
indexed data-name. An identifier that is composed of
a data-name, followed by one or more index-names instance data. Data defining the state of an object.
enclosed in parentheses. The instance data introduced by a class is defined in
the WORKING-STORAGE SECTION of the DATA
* indexed file. A file with indexed organization. DIVISION of the class definition. The state of an
object also includes the state of the instance
* indexed organization. The permanent logical file variables introduced by base classes that are
structure in which each record is identified by the inherited by the current class. A separate copy of the
value of one or more keys within that record. instance data is created for each object instance.
indexing. Synonymous with subscripting using * integer. (1) A numeric literal that does not include
index-names. any digit positions to the right of the decimal point.
* index-name. A user-defined word that names an (2) A numeric data item defined in the DATA DIVISION
index associated with a specific table. that does not include any digit positions to the right of
the decimal point.
* inheritance (for classes). A mechanism for using (3) A numeric function whose definition provides that
the implementation of one or more classes as the all digits to the right of the decimal point are zero in
basis for another class. A sub-class inherits from one the returned value for any possible evaluation of the
or more super-classes . By definition the inheriting function.
class conforms to the inherited classes.
integer function. A function whose category is
* initial program. A program that is placed into an numeric and whose definition does not include any
initial state every time the program is called in a run digit positions to the right of the decimal point.
unit.
interface. The information that a client must know to
* initial state. The state of a program when it is first use a class —the names of its attributes and the
called in a run unit. signatures of its methods . With direct-to-SOM
compilers such as COBOL, the interface to a class
inline. In a program, instructions that are executed may be defined by native language syntax for class
sequentially, without branching to routines, definitions. Classes implemented in other languages
subroutines, or other programs. might have their interfaces defined directly in SOM
Interface Definition Language (IDL). The COBOL
* input file. A file that is opened in the INPUT mode.
compiler has a compiler option, IDLGEN, to
automatically generate IDL for a COBOL class.
* input mode. The state of a file after execution of an
OPEN statement, with the INPUT phrase specified, for
Interface Definition Language (IDL). The formal
that file and before the execution of a CLOSE
language (independent of any programming language)
statement, without the REEL or UNIT phrase for that
by which the interface for a class of objects is defined
file.
in a IDL file, which the SOM compiler then interprets
to create an implementation template file and binding
* input-output file. A file that is opened in the I-O
files. SOM′s Interface Definition Language is fully
mode.
compliant with standards established by the Object
Management Group′s Common Object Request Broker
* INPUT-OUTPUT SECTION. The section of the
Architecture ( CORBA ).
ENVIRONMENT DIVISION that names the files and the
external media required by an object program or
interlanguage communication (ILC). The ability of
method and that provides information required for
routines written in different programming languages
transmission and handling of data during execution of
to communicate. ILC support allows the application
the object program or method definition.
writer to readily build applications from component
routines written in a variety of languages.
* Input-Output statement. A statement that causes
files to be processed by performing operations upon
intermediate result. An intermediate field containing
individual records or upon the file as a unit. The
the results of a succession of arithmetic operations.
input-output statements are: ACCEPT (with the
Glossary 335
* internal data. The data described in a program iteration structure. A program processing logic in
excluding all external data items and external file which a series of statements is repeated while a
connectors. Items described in the LINKAGE condition is true or until a condition is true.
SECTION of a program are treated as internal data.
* library text. A sequence of text words, comment * mass storage file. A collection of records that is
lines, the separator space, or the separator assigned to a mass storage medium.
pseudo-text delimiter in a COBOL library.
* megabyte (M). One megabyte equals 1,048,576
LILIAN DATE. The number of days since the bytes.
beginning of the Gregorian calendar. Day one is
Friday, October 15, 1582. The Lilian date format is * merge file. A collection of records to be merged by
named in honor of Luigi Lilio, the creator of the a MERGE statement. The merge file is created and
Gregorian calendar. can be used only by the merge function.
* LINAGE-COUNTER. A special register whose value metaclass. A SOM class whose instances are SOM
points to the current position within the page body. class-objects. The methods defined in metaclasses
are executed without requiring any object instances of
LINKAGE SECTION. The section in the DATA the class to exist, and are frequently used to create
DIVISION of the called program that describes data instances of the class.
items available from the calling program. These data
items may be referred to by both the calling and method. Procedural code that defines one of the
called program. operations supported by an object, and that is
executed by an INVOKE statement on that object.
literal. A character-string whose value is specified
either by the ordered set of characters comprising the * Method Definition. The COBOL source unit that
string, or by the use of a figurative constant. defines a method.
local. A set of attributes for a program execution * method identification entry. An entry in the
environment indicating culturally sensitive METHOD-ID paragraph of the IDENTIFICATION
considerations, such as: character code page, DIVISION which contains clauses that specify the
collating sequence, date/time format, monetary value method-name and assign selected attributes to the
representation, numeric value representation, or method definition.
language.
* method-name. A user-defined word that identifies a
* LOCAL-STORAGE SECTION. The section of the method.
DATA DIVISION that defines storage that is allocated
and freed on a per-invocation basis, depending on the * mnemonic-name. A user-defined word that is
value assigned in their VALUE clauses. associated in the ENVIRONMENT DIVISION with a
specified implementor-name.
* logical operator. One of the reserved words AND,
OR, or NOT. In the formation of a condition, either multitasking. Mode of operation that provides for the
AND, or OR, or both can be used as logical concurrent, or interleaved, execution of two or more
connectives. NOT can be used for logical negation. tasks. When running under the &cel. product,
multitasking is synonymous with multithreading .
* logical record. The most inclusive data item. The
level-number for a record is 01. A record may be MVS/XA* (Multiple Virtual Storage/Extended
either an elementary item or a group of items. The Architecture). An IBM operating system that
term is synonymous with record. manages multiple virtual address spaces in IBM
processors operating in extended architecture mode.
* low order end. The rightmost character of a string MVS/XA supports the 31-bit addressing mechanism of
of characters. extended architecture mode, and therefore, allows an
address space as large as 2 31 bytes (2048 megabytes
or 2 gigabytes).
M
main program. In a hierarchy of programs and N
subroutines, the first program to receive control when
the programs are run. name. A word composed of not more than 30
characters that defines a COBOL operand.
* mass storage. A storage medium in which data
may be organized and maintained in both a * native character set. The implementor-defined
sequential and nonsequential manner. character set associated with the computer specified
in the OBJECT-COMPUTER paragraph.
Glossary 337
* native collating sequence. The implementor-defined * numeric literal. A literal composed of one or more
collating sequence associated with the computer numeric characters that may contain either a decimal
specified in the OBJECT-COMPUTER paragraph. point, or an algebraic sign, or both. The decimal point
must not be the rightmost character. The algebraic
* negated combined condition. The ‘NOT’ logical sign, if present, must be the leftmost character.
operator immediately followed by a parenthesized
combined condition.
O
* negated simple condition. The ‘NOT’ logical
operator immediately followed by a simple condition. object. An entity that has state (its data values) and
operations (its methods). An object is a way to
nested program. A program that is directly contained encapsulate state and behavior.
within another program.
object code. Output from a compiler or assembler
* next executable sentence. The next sentence to that is itself executable machine code or is suitable
which control will be transferred after execution of the for processing to produce executable machine code.
current statement is complete.
* OBJECT-COMPUTER. The name of an
* next executable statement. The next statement to ENVIRONMENT DIVISION paragraph in which the
which control will be transferred after execution of the computer environment, within which the object
current statement is complete. program is executed, is described.
* next record. The record that logically follows the * object computer entry. An entry in the
current record of a file. OBJECT-COMPUTER paragraph of the ENVIRONMENT
DIVISION which contains clauses that describe the
* noncontiguous items. Elementary data items in the computer environment in which the object program is
WORKING-STORAGE and LINKAGE SECTIONs that to be executed.
bear no hierarchic relationship to other data items.
object deck. A portion of an object program suitable
* nonnumeric item. A data item whose description as input to a linkage editor. Synonymous with object
permits its content to be composed of any module and text deck .
combination of characters taken from the computer’s
character set. Certain categories of nonnumeric object module. Synonym for object deck or text deck .
items may be formed from more restricted character
sets. * object of entry. A set of operands and reserved
words, within a DATA DIVISION entry of a COBOL
* nonnumeric literal. A literal bounded by quotation program, that immediately follows the subject of the
marks. The string of characters may include any entry.
character in the computer’s character set.
* object program. A set or group of executable
null. Figurative constant used to assign the value of machine language instructions and other material
an invalid address to pointer data items. NULLS can designed to interact with data to provide problem
be used wherever NULL can be used. solutions. In this context, an object program is
generally the machine language result of the
* numeric character. A character that belongs to the operation of a COBOL compiler on a source program.
following set of digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Where there is no danger of ambiguity, the word
‘program’ alone may be used in place of the phrase
numeric-edited item. A numeric item that is in such a ‘object program.’
form that it may be used in printed output. It may
consist of external decimal digits from 0 through 9, * object time. The time at which an object program is
the decimal point, commas, the dollar sign, editing executed. The term is synonymous with execution
sign control symbols, plus other editing symbols. time.
* numeric function. A function whose class and * obsolete element. A COBOL language element in
category are numeric but which for some possible Standard COBOL that is to be deleted from the next
evaluation does not satisfy the requirements of revision of Standard COBOL.
integer functions.
ODO object. In the example below,
* numeric item. A data item whose description
WORKING-STORAGE SECTION
restricts its content to a value represented by 01 TABLE-1.
characters chosen from the digits from ‘0’ through ‘9’; 05 X PICS9.
if signed, the item may also contain a ‘ + ’, ‘ − ’, or 05 Y OCCURS 3 TIMES
other representation of an operational sign. DEPENDING ON X PIC X.
Glossary 339
* phrase. A phrase is an ordered set of one or more performed procedures. Contained program procedure
consecutive COBOL character-strings that form a integration is the process where a CALL to a
portion of a COBOL procedural statement or of a contained program is replaced by the program code.
COBOL clause.
* procedure-name. A user-defined word that is used
* physical record. See “block.” to name a paragraph or section in the Procedure
Division. It consists of a paragraph-name (which may
pointer data item. A data item in which address be qualified) or a section-name.
values can be stored. Data items are explicitly
defined as pointers with the USAGE IS POINTER procedure-pointer data item. A data item in which a
clause. ADDRESS OF special registers are implicitly pointer to an entry point can be stored. A data item
defined as pointer data items. Pointer data items can defined with the USAGE IS PROCEDURE-POINTER
be compared for equality or moved to other pointer clause contains the address of a procedure entry
data items. point.
portability. The ability to transfer an application * program identification entry. An entry in the
program from one application platform to another PROGRAM-ID paragraph of the IDENTIFICATION
with relatively few changes to the source program. DIVISION which contains clauses that specify the
program-name and assign selected program
preloaded. In COBOL this refers to COBOL programs attributes to the program.
that remain resident in storage under IMS instead of
being loaded each time they are called. * program-name. In the IDENTIFICATION DIVISION
and the end program header, a user-defined word
* prime record key. A key whose contents uniquely that identifies a COBOL source program.
identify a record within an indexed file.
* pseudo-text. A sequence of text words, comment
* priority-number. A user-defined word which lines, or the separator space in a source program or
classifies sections in the Procedure Division for COBOL library bounded by, but not including,
purposes of segmentation. Segment-numbers may pseudo-text delimiters.
contain only the characters ′0′,′1′, ... , ′9′. A
segment-number may be expressed either as a one- * pseudo-text delimiter. Two contiguous equal sign
or two-digit number. characters (==) used to delimit pseudo-text.
* record area. A storage area allocated for the * relational operator. A reserved word, a relation
purpose of processing the record described in a character, a group of consecutive reserved words, or
record description entry in the File Section of the a group of consecutive reserved words and relation
DATA DIVISION. In the File Section, the current characters used in the construction of a relation
number of character positions in the record area is condition. The permissible operators and their
determined by the explicit or implicit RECORD clause. meanings are:
recursively capable. A program is recursively * relation character. A character that belongs to the
capable (can be called recursively) if the RECURSIVE following set:
attribute is on the PROGRAM-ID statement.
Character Meaning
reel. A discrete portion of a storage medium, the
dimensions of which are determined by each > greater than
implementor that contains part of a file, all of a file, or < less than
any number of files. The term is synonymous with = equal to
unit and volume.
Glossary 341
* relation condition. The proposition, for which a
truth value can be determined, that the value of an S
arithmetic expression, data item, nonnumeric literal,
SBCS (Single Byte Character Set). See ″ Single Byte
or index-name has a specific relationship to the value
Character Set (SBCS) ″ .
of another arithmetic expression, data item,
nonnumeric literal, or index name. (See also
scope terminator. A COBOL reserved word that
“relational operator.”)
marks the end of certain Procedure Division
statements. It may be either explicit (END-ADD, for
* relative file. A file with relative organization.
example) or implicit (separator period).
* relative key. A key whose contents identify a
* section. A set of zero, one or more paragraphs or
logical record in a relative file.
entities, called a section body, the first of which is
* relative organization. The permanent logical file preceded by a section header. Each section consists
structure in which each record is uniquely identified of the section header and the related section body.
by an integer value greater than zero, which specifies
* section header. A combination of words followed by
the record’s logical ordinal position in the file.
a separator period that indicates the beginning of a
* relative record number. The ordinal number of a section in the Environment, Data, and Procedure
record in a file whose organization is relative. This Divisions. In the ENVIRONMENT and DATA
number is treated as a numeric literal which is an DIVISIONs, a section header is composed of reserved
integer. words followed by a separator period. The
permissible section headers in the ENVIRONMENT
* reserved word. A COBOL word specified in the list DIVISION are:
of words that may be used in a COBOL source CONFIGURATION SECTION.
program, but that must not appear in the program as INPUT-OUTPUT SECTION.
user-defined words or system-names.
The permissible section headers in the DATA
* resource. A facility or service, controlled by the DIVISION are:
operating system, that can be used by an executing FILE SECTION.
program. WORKING-STORAGE SECTION.
LOCAL-STORAGE SECTION.
* resultant identifier. A user-defined data item that is LINKAGE SECTION.
to contain the result of an arithmetic operation.
In the Procedure Division, a section header is
composed of a section-name, followed by the
reusable environment. A reusable environment is
reserved word SECTION, followed by a separator
when you establish an assembler program as the
period.
main program by using either ILBOSTP0 programs,
IGZERRE programs, or the RTEREUS run-time option.
* section-name. A user-defined word that names a
section in the Procedure Division.
routine. A set of statements in a COBOL program
that causes the computer to perform an operation or
selection structure. A program processing logic in
series of related operations. In &cel., refers to either
which one or another series of statements is
a procedure, function, or subroutine.
executed, depending on whether a condition is true or
false.
* routine-name. A user-defined word that identifies a
procedure written in a language other than COBOL.
* sentence. A sequence of one or more statements,
the last of which is terminated by a separator period.
* run time. The time at which an object program is
executed. The term is synonymous with object time.
* separately compiled program. A program which,
together with its contained programs, is compiled
run-time environment. The environment in which a
separately from all other programs.
COBOL program executes.
* separator. A character or two contiguous
* run unit. A stand-alone object program, or several
characters used to delimit character-strings.
object programs, that interact via COBOL CALL
statements, which function at run time as an entity.
* separator comma. A comma (,) followed by a space
used to delimit character-strings.
Glossary 343
sequences; and relating class-names to sets of * symbolic-character. A user-defined word that
characters. specifies a user-defined figurative constant.
* special registers. Certain compiler generated syntax. (1) The relationship among characters or
storage areas whose primary use is to store groups of characters, independent of their meanings
information produced in conjunction with the use of a or the manner of their interpretation and use. (2) The
specific COBOL feature. structure of expressions in a language. (3) The rules
governing the structure of a language. (4) The
* standard data format. The concept used in relationship among symbols. (5) The rules for the
describing the characteristics of data in a COBOL construction of a statement.
DATA DIVISION under which the characteristics or
properties of the data are expressed in a form * system-name. A COBOL word that is used to
oriented to the appearance of the data on a printed communicate with the operating environment.
page of infinite length and breadth, rather than a form
oriented to the manner in which the data is stored System Object Model (SOM). IBM′s object-oriented
internally in the computer, or on a particular external programming technology for building, packaging, and
medium. manipulating class libraries. SOM conforms to the
Object Management Group′s (OMG) Common Object
* statement. A syntactically valid combination of Request Broker Architecture (CORBA) standards.
words, literals, and separators, beginning with a verb,
written in a COBOL source program.
T
structured programming. A technique for organizing
and coding a computer program in which the program * table. A set of logically consecutive items of data
comprises a hierarchy of segments, each segment that are defined in the DATA DIVISION by means of
having a single entry point and a single exit point. the OCCURS clause.
Control is passed downward through the structure
without unconditional branches to higher levels of the * table element. A data item that belongs to the set
hierarchy. of repeated items comprising a table.
* sub-class. A class that inherits from another class. text deck. Synonym for object deck or object module .
When two classes in an inheritance relationship are
considered together, the sub-class is the inheritor or * text-name. A user-defined word that identifies
inheriting class; the super-class is the inheritee or library text.
inherited class.
* text word. A character or a sequence of contiguous
* subject of entry. An operand or reserved word that characters between margin A and margin R in a
appears immediately following the level indicator or COBOL library, source program, or in pseudo-text
the level-number in a DATA DIVISION entry. which is:
• A separator, except for: space; a pseudo-text
* subprogram. See “called program.” delimiter; and the opening and closing delimiters
for nonnumeric literals. The right parenthesis and
* subscript. An occurrence number represented by left parenthesis characters, regardless of context
either an integer, a data-name optionally followed by within the library, source program, or pseudo-text,
an integer with the operator + or -, or an index-name are always considered text words.
optionally followed by an integer with the operator +
• A literal including, in the case of nonnumeric
or -, that identifies a particular element in a table. A
subscript may be the word ALL when the subscripted literals, the opening quotation mark and the
identifier is used as a function argument for a function closing quotation mark that bound the literal.
allowing a variable number of arguments. • Any other sequence of contiguous COBOL
characters except comment lines and the word
* subscripted data-name. An identifier that is ‘COPY’ bounded by separators that are neither a
composed of a data-name followed by one or more separator nor a literal.
subscripts enclosed in parentheses.
top-down design. The design of a computer program
* super-class. A class that is inherited by another using a hierarchic structure in which related functions
class. See also sub-class . are performed at each level of the structure.
switch-status condition. The proposition, for which a top-down development. See “structured
truth value can be determined, that an UPSI switch, programming.”
capable of being set to an ‘on’ or ‘off’ status, has
been set to a specific status.
* unary operator. A plus (+) or a minus (-) sign, that * variably located item.. A data item following, and
precedes a variable or a left parenthesis in an not subordinate to, a variable-length table in the
arithmetic expression and that has the effect of same level-01 record.
multiplying the expression by +1 or -1, respectively.
* verb. A word that expresses an action to be taken
unit. A module of direct access, the dimensions of by a COBOL compiler or object program.
which are determined by IBM.
VM/SP (Virtual Machine/System Product). An
universal object reference. A data-name that can IBM-licensed program that manages the resources of
refer to an object of any class. a single computer so that multiple computing systems
appear to exist. Each virtual machine is the
* unsuccessful execution. The attempted execution of functional equivalent of a “real” machine.
a statement that does not result in the execution of all
the operations specified by that statement. The volume. A module of external storage. For tape
unsuccessful execution of a statement does not affect devices it is a reel; for direct-access devices it is a
any data referenced by that statement, but may affect unit.
status indicators.
volume switch procedures. System specific
UPSI switch. A program switch that performs the procedures executed automatically when the end of a
functions of a hardware switch. Eight are provided: unit or reel has been reached before end-of-file has
UPSI-0 through UPSI-7. been reached.
* variable. A data item whose value may be changed * WORKING-STORAGE SECTION. The section of the
by execution of the object program. A variable used DATA DIVISION that describes working storage data
in an arithmetic expression must be a numeric items, composed either of noncontiguous items or
elementary item. working storage records or of both.
Glossary 345
346 IBM VA for COBOL OO Programming
List of Abbreviations
AD application development FAT file allocation table GUI
API application program interface graphical user interface
CORBA Common Object Request IBM International Business
Broker Machines Corporation
CRC class responsibilities IT information technology
collaborations
ITSO International Technical
DDE dynamic data exchange Support Organization
DDL data description language LE language environment
DFD data flow diagram MVC model view controller
DLL dynamic link library OMG Object Management Group
DSOM distributed system object OTC Object Technology Council
model
PAM project access method
ER entity relationship
PDS partitioned data set
SOM system object model
A O
analyzing objects 114 object interaction diagram 138, 158, 176
ANSI standards 35 object language comparison 43
object references 71
objects definition 59
C OMG (Object Management Group) 8, 22, 40
class 16, 59, 60, 65 OO analysis and design 113
class instance 16 OO analysis procedures
class programs 56 CRC card formulation 113
class structure method determination 113
as objects 59 object identification 113
COBOL program structure 61 use cases 113
definition statements 62 OO COBOL implementation 47
client programs 56 OO design 114
client structure OTC (Object Technology Council) 8
COBOL program structure 69
definition statements
example logic flow 69 P
client/class relationship 32 polymorphism 12, 15, 19, 27
compiler command 56
CORBA (Common Object Request Broker
Architecture) 41 R
CRC cards 113 recursion 33
D S
DSOM (Distributed System Object Model) 40 SOM (System Object Model) 5, 37, 61, 62, 121, 123
subclass structure
definition statements 83
E method definition 84
encapsulation 12, 13, 19, 26 subclasses 81
explicit definitions 31 superclass 83
superclass data acquisition 85
I
inheritance 12, 14, 19, 26 U
use case analysis
basic 114
L class coding 121
limitations of 3GL COBOL 28 coding process 121
methods 116
objects 115
M testing client 121
message 17
metaclass structure
definition statements 99 W
metaclasses 97 wrappering 47
method structure
COBOL program structure 65
definition statements 66
methods 13, 59, 60, 65
Your feedback is very important to help us maintain the quality of ITSO Bulletins. Please fill out this
questionnaire and return it using one of the following methods:
• Mail it to the address on the back (postage paid in U.S. only)
• Give it to an IBM marketing representative for mailing
• Fax it to: Your International Access Code + 1 914 432 8246
• Send a note to [email protected]
Name Address
Company or Organization
Phone No.
IBML
ITSO Technical Bulletin Evaluation RED000 Cut or Fold
Along Line
SG24-4606-00
NO POSTAGE
NECESSARY
IF MAILED IN THE
UNITED STATES
Cut or Fold
SG24-4606-00 Along Line
IBML
Printed in U.S.A.
SG24-4606-00