A Framework For Building Financial Models: Yoder Email: Yoder@Cs - Uiuc.Edu
A Framework For Building Financial Models: Yoder Email: Yoder@Cs - Uiuc.Edu
Table of Contents
1. 2. INTRODUCTION ................................................................................................................................................... 1 FINANCIAL MODEL SPECIFICATION.............................................................................................................. 1 2.1 2.2 2.3 2.4 2.5 3. 3.1 3.2 3.3 3.4 3.5 4. 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 4.16 4.17 5. 5.1 5.2 5.3 5.4 5.5 5.6 5.7 6. 7. 8. 9. 10. DUPONTMODEL ................................................................................................................................................. 1 DRILLING-DOWN ................................................................................................................................................ 3 DETAILED TRANSACTIONS .................................................................................................................................. 3 SUMMARY REPORTS............................................................................................................................................ 4 GRAPHS ............................................................................................................................................................. 5 WHAT HAPPENS IN THE FINANCIAL MODEL APPLICATION ..................................................................................... 6 FINANCIAL MODEL ARCHITECTURE ..................................................................................................................... 8 HOW IT ALL FITS TOGETHER ................................................................................................................................ 9 HOW TO SPECIFY A FM ......................................................................................................................................11 REPORTVALUES.................................................................................................................................................13 CREATING DUPONT MODELS .............................................................................................................................19 BUSINESS LOGIC AND GUI SPECIFICATION DATA MODEL ....................................................................................20 REPORTVALUE DETAILS ....................................................................................................................................22 VALUEMODEL ...................................................................................................................................................24 QUERIES............................................................................................................................................................25 QUERYEXPRESSIONS ..........................................................................................................................................28 SELECTION CRITERION.......................................................................................................................................30 SPECIFYING SELECTION CRITERION ....................................................................................................................32 FMSTATE .........................................................................................................................................................34 APPLICATIONINFO .............................................................................................................................................34 SESSIONS...........................................................................................................................................................34 NAMESPACES.....................................................................................................................................................35 SUMMARYREPORT FRAMEWORK.........................................................................................................................36 GRAPHING FRAMEWORK ....................................................................................................................................36 DETAILEDREPORT FRAMEWORK .........................................................................................................................37 PRINTING FRAMEWORK......................................................................................................................................38 TESTING FRAMEWORK .......................................................................................................................................38 SECURITY REQUIREMENTS .................................................................................................................................38 COMPONENTS ....................................................................................................................................................39 HOW SECURITY REQUIREMENTS ARE MET ............................................................................................................39 OTHER REQUIREMENTS ......................................................................................................................................40 SECURITY DATA MODEL ....................................................................................................................................40 SECURITYADMIN TOOLS ....................................................................................................................................41 FMLOGIN PROCESS ...........................................................................................................................................42
SECURITY MODULE...........................................................................................................................................38
FUTURE WORK ...................................................................................................................................................48 SUMMARY ............................................................................................................................................................48 PATTERNS ............................................................................................................................................................49 REFERENCES.......................................................................................................................................................50 APPENDIX - THE FARM DATA MODEL ......................................................................................................50
Figures
FIGURE 1 - DUPONT MODEL ............................................................................................................................................... 2 FIGURE 2 - DRILL DOWN ON INVENTORIES .......................................................................................................................... 3 FIGURE 3 - PRIME PRODUCTS INVENTORY DETAILED TRANSACTIONS ................................................................................... 4 FIGURE 4 - PRIME PRODUCTS INVENTORY SUMMARY REPORT .............................................................................................. 4 FIGURE 5 - PRIME PRODUCTS INVENTORY GRAPH ................................................................................................................ 5 FIGURE 6 - VALUE MODELS IN GUIS ................................................................................................................................... 7 FIGURE 7 - FINANCIAL MODEL APPLICATION OVERVIEW...................................................................................................... 7 FIGURE 8 - USER VIEW OF THE FINANCIAL MODEL LAYERED ARCHITECTURE ....................................................................... 9 FIGURE 9 - BUILDER VIEW OF THE FINANCIAL MODEL LAYERED ARCHITECTURE .................................................................10 FIGURE 10 - FINANCIAL MODEL CREATIONAL DIAGRAM .....................................................................................................11 FIGURE 11 - WHAT HAPPENS .............................................................................................................................................12 FIGURE 12 - REPORTVALUE ..............................................................................................................................................13 FIGURE 13 - DRILL DOWN VALUES ....................................................................................................................................14 FIGURE 14 - REPORTVALUES GUI SPECIFICATIONS ...........................................................................................................15 FIGURE 16 - REPORTVALUES BUSINESS LOGIC SPECIFICATION ...........................................................................................16 FIGURE 18 - REPORTVALUES CREATIONAL DIAGRAM .........................................................................................................17 FIGURE 20 - STRUCTURAL DIAGRAM OF REPORTVALUES ....................................................................................................18 FIGURE 22 - BUSINESS LOGIC AND GUI DATA MODEL ........................................................................................................20 FIGURE 23 BUSINESS LOGIC AND GUI ENTITY RELATIONSHIP DIAGRAM .............................................................................21 FIGURE 24 - OBJECT STRUCTURE DIAGRAM FOR VALUEMODEL ...........................................................................................25 FIGURE 25 - DYNAMIC STRUCTURE OF QUERYOBJECTS .....................................................................................................27 FIGURE 26 - OBJECT DIAGRAM FOR QUERYOBJECT ...........................................................................................................27 FIGURE 27 - QUERYEXPRESSION'S OBJECT DIAGRAM ........................................................................................................28 FIGURE 28 - DYNAMIC STRUCTURE OF QUERYEXPRESSIONS..............................................................................................29 FIGURE 29 - AURORA SELECTION BOX ...............................................................................................................................30 FIGURE 30 - SPECIFYING SELECTION CRITERIA ...................................................................................................................31 FIGURE 31 - SELECTIONCRITERION STRUCTURE ................................................................................................................32 FIGURE 32 - SELECTIONCRITERIONEDITOR EDITOR...........................................................................................................33 FIGURE 33 - SECURITY DATA MODEL ................................................................................................................................40 FIGURE 34 - SECURITY ADMIN...........................................................................................................................................41 FIGURE 35 - USERPROPERTIESDIALOG ...............................................................................................................................42 FIGURE 36 - LOGIN PROCESS .............................................................................................................................................43 FIGURE 37 - FMLOGINDIALOG ..........................................................................................................................................43 FIGURE 38 - LOGIN FAILURE LOOP .....................................................................................................................................44 FIGURE 39 - APPLICATION SETUP .......................................................................................................................................45 FIGURE 40 - OTHER SECURITY CHECKS ..............................................................................................................................45 FIGURE 41 - NODE SECURITY .............................................................................................................................................46 FIGURE 42 - PROFILE SECURITY .........................................................................................................................................46 FIGURE 43 - ROLE SECURITY .............................................................................................................................................47 FIGURE 44 - PASSWORD SECURITY .....................................................................................................................................47 FIGURE 45 - FINANCIAL MODEL START UP .........................................................................................................................48 FIGURE 46 - FARM DATA MODEL .......................................................................................................................................52 ii
1. Introduction
We've been working for over two years on a fairly large financial modeling project with Caterpillar. Our main result is a framework for financial modeling. It lets you quickly build applications that examine financial data stored in a database and produces profit and loss statements, balance sheets, detailed analysis of departments, sales regions, and business lines, with the ability to drill down until you hit individual transactions. It lets you budget and correct errors in the data, too. We believe that once the business specific data model has been built (which currently takes a long time in Caterpillar because most of their data has to be taken from many sources, and every business unit is different and so has to define its own data model) that it will only take a week or two to build the rest of the system. We are able to define a complete system for any business unit without any Smalltalk programming. The business model is stored in the database, not written in Smalltalk, and we plan to have a GUI for building it. The menus, reports, drill-downs, and graphs are also stored in the database. We have also implemented GUIs for defining all of the GUIs and business logic. The financial modeling framework allows one to build a Financial Model application for nearly any type of business. Although it was hard to figure out a good architecture for building Financial Models, the actual architecture for the Financial Model is not complicated and can easily be reproduced. Most importantly, the architecture is language independent. It can be implemented in any language, and once implemented, knowledgeable users can build domain-specific applications without programming. This allows domain experts to design the applications and allows end-users to customize them. The primary principle here is to not program in a general purpose language, rather program in a higher-level domain-specific language. You can do more with a general purpose language but with the higher level language you can program within a limited domain with fewer lines of code. This work provides a visualobject-oriented programming language [Burnett, Goldberg, Lewis 1995] to allow one to program without feeling like they are programming. They are designing the application in terms of domain specifics that they are familiar with. [reference Book on Visual Programming by Goldberg here].
2.1 DuPontModel
The DuPontModel [Johnson & Kaplan, 1987] (see Figure 1) is a graphical model of a view of Profit/Loss statements for businesses. It provides a quick way for managers and accountants to view their return on assets. Some of the boxes in Figure 1 are simply calculations from other values while others are the result of querying values from a database. Each of the values based upon queries from a database can be viewed in more detail by simply clicking on the button above its value. This will open up a more detailed report which allows for customized views on the data of interest. The following account of the development of the DuPont 1
is taken directly from the book "Relevance Lost: The Rise and Fall of Management Accounting", written by H. Thomas Johnson and Robert S. Kaplan.
The DuPont Powder Company was an explosives firm founded in 1903 by three DuPont cousins, Alfred, Coleman, and Pierre. Upon acquisition of the company the three cousins began to develop a new adminstrative structure so that they might better evaluate and control the company operations. Thenew structure involved consolidating the company's operations. The Powder company became a centrally managed entreprise coordinating throught its own departments most of the manufacturing and distribution activities formerly mediated through the market by scores of specialized firms. A big key to the new corporate structure was the development of a centralized accounting system. The home office requested from the company's mills and branch sales offices, which were located throughout the United states, daily and weekly data on sales, payroll, and manufacturing costs. The company wanted to use this data to constantly monitor the financial performance of all the branch divisions. With the company structure and accounting system in place, all that was left to do is develop a tool. The companies intense desire to assess every aspect of the company's activities in terms of the price of capital led the founders of the DuPont Powder Company to devise an ingenious return on investment formula. That formula is what has come to be known as the DuPont model. The breakdown of the DuPont formula helps see how return on investment is affected by a change in any element from either the income statement or the balance sheet. Viewed from this perspective, the DuPont return on investment formula is an ideal tool for controlling, with accounting numbers, any verticall integrated company's opertions. On interesting side note. It appears that the idea for the DuPont return on investment formula originated with F. Donaldson Brown. Brown was a college-trained electrical engineer and one-time electrical equipment salesman. Brown had no formal accounting training. It is believed that Brown's profiency in mathematics, sales experience, and engineering and marketing skills gave him a uniques perspective on the determinants of company performance.
2.2 Drilling-Down
Viewing the source of a value is called drilling down. When the user drills-down on a specified value, they get a report similar to the one seen in Figure 2. This drill-down on Inventories is a first level report that shows where the DuPontModel Inventories values come from. This report is created dynamically and can be customized by the user. Note that the Budget and Actual columns are derived directly from database queries while Profit +/- and % Change are extra columns that are calculated as any mathematical function of the previous columns. These calculated columns can be defined by the GUI developer and it is possible to allow the end-user to specify these. Whenever the user changes the selection criteria that the queries are based upon, the new values based upon the changed queries are automatically propagated to all open windows.
Figure 2 - Drill Down on Inventories From here the user can open up customizable summary, graph, and detailed reports. This is done by either selecting the desired report from a user-defined menu item or by clicking on one of the rows in the table which has a user-defined report associated with it. Although our current system has the application-builder (domain-expert) define these reports ahead of time, our framework does make it possible to allow for the enduser to dynamically create these reports.
2.5 Graphs
Graph reports as seen in Figure 5 allow the user to specify the type of graph (bar, line, pareto, band stacked), the orientation, the legends, and other viewing options. These graphs can be built either on SQL-Queries for values from the database, or from pre-calculated values. Once again, although these are currently pre-defined by the application-builder, our framework allows for GUI extensions that could have end-users defining there graphs at run-time.
DuPontModel - A graphical view of the return on sales. ReportModel - Builds a spreadsheet interface using values and GUI descriptions from ReportValues. GraphReports Framework - Used to graph any desired values from the database. SummaryReports Framework - Gives a summary view on values from the database. DetailedWindows Framework - Allows users to edit and view individual transactions from the database.
QueryObjects - Used to create queries into the database. ReportValues - Specifies the business logic and GUI for reports. SelectionCriteria - Allows for the dynamic creation of desired selection values. This works in conjunction with QueryObjects to allows users to select their values of interest.
I.
Utility Frameworks Printing Module - Allows any window to print itself with a user selected output Security Module - Insures that only desired users can edit and/or view the data. This is configurable by an administrative module. Testing Framework - This works in conjunction with the report values and the selection criteria. It automatically selects values from the database and insures you have the desired results.
If the specified date range or products of interest changes, the query automatically re-queries the database and the changes are propagated through the ValueModels to the display. The specifics of ValueModels and QueryObjects are discussed later. There is a set of equations making up the business logic for a company. This business logic is built upon a complicated data model representing all of the financial data. The business unit data model that we designed used the Stars Patterns [Steve Petterson]. This financial data could be relation or legacy data. The financial model application takes this business logic and builds different customizable views to the data.
Sales Report
budget actual variance VM
$ 5,000
Select all sales from North America for the specified date and products which returns $5,000,000
Figure 6 - Value Models in GUIs Figure 7 gives a high-level overview of what happens. The application builds the values based upon the specified business logic and returned values from the database, and then builds an appropriate GUI and plugs the values into the GUIs. The application does the constructing of GUIs and Values. The GUIs really take basic building block provided by the system and puts them together to provide the desired view. The Values are constructed automatically from the business logic that is stored in the database.
Application
GUI
Values
(based on Business Logic)
Report Model
Report Values Editor Type Table Interfaces
Dupont Model
GUI Layer
Report Values
Reports Menu Specs Element Specs Window Specs Queries State
FM State
Windows Values App Info Seletion
Value Model
arithmetic
Query Expression
Query Object
Composition Layer
A DuPontModel can also open up an report showing where each of its displayed values came from. It does this by requesting a specific ReportValue to open up a report on itself. A ReportValue knows what its view looks likes that it wants to open and also contains the business logic associated with the view to open. It takes this descriptive information and opens up a ReportModel which is the combination of the desired view and business logic.
Report Values
Reports Menu Specs Element Specs Window Specs Queries State
FM State
Windows Values App Info Seletion
Dupont Model Summary Report Detailed Report Value Model Graph Report Report Model GUI Layer Composition Layer
arithmetic
Query Expression
Query
A ReportModel is also given information for opening up other reports for the specific ReportValue. These reports consist of other summaries, graphs, and detailed transactions. This information is built up into menus and clicking actions on the reports which call the appropriate method in the specific ReportValue via FMState.
10
START
SecurityModule
1) loads
ApplicationInfo
3) Opens: (FmState)
2) Creates: (AppInfo)
Creates: (FmState)
ReportValues
Summary Report Creates: (FmState) Detailed Report Report Model Graph Report Formula Report Opens: (FmState)
11
queries are still obtained from the ReportValues but then a direct connection is made for any needed values and/or updates.
GUI Descriptions
Business Logic
NetSales Report/Values
Detailed Values
Vehicle Summary
Vehicle Summary
90 80 70 60 50 40 30 20 10 0 1st Qtr 2nd Qtr 3rd Qtr 4th Qtr
1st Qtr
2nd Qtr
3rd Qtr
4th Qtr
3.5 ReportValues
A ReportValue holds a specific value to be displayed and also knows the rules for calculating that value (i.e. the business logic and the GUI descriptions). A ReportValue can also drill down on its value, showing how the values are calculated. It uses the same rules for calculating its value that it does for creating the GUI, so the GUI and the values are always consistent. Usually the GUI shows a spreadsheet of some kind. It lets the user drill down on the value in the spreadsheet in several ways, perhaps by drawing graphs, perhaps by showing detailed lists of transactions, perhaps by opening the GUI for the next lower ReportValue. The primary function of a ReportValue is to allow values to be built based upon the specified business logic and to allow for users to selectively slice and dice these values to get the desired summary, graph, and detailed views. The rules for calculating values are often complex. Consider the report for Inventory. It calculates Inventory according to the formula Inventory = Prime Products Inventory + Parts Inventory. Prime Products and Parts Inventory are computed by querying the database, i.e. they correspond to SQL queries. Figure 13 shows the GUI with values plugged in. The menus are automatically generated from the Business Logic and GUI
Report Value
Business Logic
Element Specs Queries
GUI Descriptions
Reports Menu Specs Window Specs
Figure 12 - ReportValue Descriptions as well. It is up to the application designer to specify what data to display 1. 2. 3. The DuPontModel will display the total value of the entire ReportValues group information. The next drill-down level displays a more specific information in report tables. The reports from the drill-down can be one of three more specific views of the data. a) The user can view the current or more specific information in a graphic form. b) The user can obtain other summary information on the current tables. c) The user can obtain the database tables detailed row level information. These will either return all of the rows for the specified selections or they can specify a selected list of the rows they are interested in. If the user is permited by the security module, they can edit these transactions and save them back to the database. They can also sort the rows on any columns they desire.
As can be seen in Figure 13, the drill-down report of Inventories are values obtained from two tables of the database, prime_products_sums and prod_stores_sums. The GUI interface of this window is designed following the ReportValues GUI Specifications for the Inventories report.
ReportValues GUI Specifications in Figure 14 shows an example of the GUI specifications for the report. The window level specifications are defined in ReportInterfaceSpec. The specifications include the column labels, the label of the window, the table specifications, and the functions for calculating some of the columns. The value of some of the columns are obtained from the queries, but some other columns, Profit +/- and % Change, are calculated from the values of the other columns. It is indicated in the picture below, the Profit +/- is the Actual column minus the Budget column. % Change column, moreover, is the Profit +/- column divided by the Actual column. These calculated columns can also be stored in the business logic descriptions in the database.
Each tables specifications are in TableInterfaceSpec. It holds the name of each table, which can be displayed if desired, and the collection of row specifications. It is shown in Error! Reference source not found. that the first tables label is shown, but not that of the second table. In actuality, the second table, which is called the total table, is generated automatically. The application builder only needs to indicate whether or not that table is to be shown and how to calculate it. The default for the total table is to add up the total of all of the other tables, but this arithmetic formula can be changed. Each rows specifications are in TableRowSpec. It holds the label of the row, which is shown on the left side of the tables, the values for each column, and the source of the values. Each value corresponds to a ValueModel object which is inserted into each element on the row. Therefore you can notice each ValueModel holding a number corresponding to each cell in the above picture. The source of these values can be obtained from various sources. They can be obtained from the ElementSpec objects. They can also be obtained from the total of other ReportInterfaceSpecs or TableInterfaceSpecs or TableRowSpecs. In fact, although it is not shown in this picture, arithmetic operations can also be performed on the totals of these specs. For example, you may want another table which holds one row that divides the Prime Products row by the Production Stores row.
14
ValueModel 3273 TableRowSpec Label: Prime Products ValueSource: prime ColumnValues: ValueModel 77585 ValueModel 23.7086 ValueModel 26000 ValueModel 26525 ValueModel 525 ValueModel .0202 ValueModel 29273 ValueModel 107382 ValueModel 78110 ValueModel 2.6684 Figure 14 - ReportValues GUI Specifications ValueModel 80857
TableInterfacesSpec ColumnLabels: (Budget, Actual, Profit +/-, % Change) WindowLabel: Inventories Functions: 3 = 2-1 4 = 3/2 Tables: Table1 Table2
TableInterfaceSpec Name: Inventories Rows: Row1 TableRowSpec Label: INVENTORIES ValueSource: TotalTable ColumnValues:
ReportValues Business Logic Specification in Figure 15 shows the structure of the collection of ElementSpecsHolder and QueriesHolder. As you can see from below, the ElementSpecs are ultimately dependent on the QueryObjects. But they can also be an arithmetic operation of two other objects. In the case below, the ElementSpecsHolder has prime pointing to a CompositeElementSpec, which is an ElementSpec divided by the number of months selected. The child ElementSpec in turn points to a QueryObject with the information about how to sum up the rows returned from the query.
A direct dependence on the queries is undesirable because database queries are so expensive. If there are many queries, then it can take a long time to get all the values from the queries. In fact, there are many redundancies, where several queries may be accessing the same database table to obtain only slightly different values. So it is preferable to query as little as possible. One effective way of minimizing queries is by getting all the needed values in few large queries and then selecting the desired values from those query values. The selection of the query values is done by the ElementSpecs. Although heavy arithmetic calculations are now performed on the client side, the reduction of the number of queries results in a performance improvement. It is up to the user to determine the optimal division between queries and the element specifications. Also, query values are cached 15
into memory and held there until the desired values are no longer needed or the selection criteria the values are based upon changes. This minimizes the amount of network traffic since if we already have queried for the desired value, we can just use it without re-establishing a connection to the database. CompositeElementSpec operation: / ElementSpec1: ElementSpec ElementSpec2: numOfMonths ElementSpec Query: prime SumField: primeDollars QueryObject Select * from PrimeProductsInvSums
Figure 16 shows the creational diagram of ReportValues and ReportModel. ReportValues must first create its specs by querying for them from the database. This includes ReportGraphSpecs, ReportDetailedTableSpecs, and ReportSummarySpecs. Other objects are also created from the specifications in the database. They are the menu which is used for the report, QueriesHolder, and ElementSpecsHolder. QueriesHolder, and ElementSpecsHolder need ReportValues for proper creation. Once these are created, the ReportModel can be opened. The ReportModel needs information about FMState, and Menu for the ReportValues to be properly created. It is the ReportModel that prompts the opening of the DetailedTable, TableGraph, and SummaryReportModel windows. The creation of these objects is actually done on the ReportValues side since the menu holds blocks from ReportValues that are evaluated when selected. One exception is TableGraph. ReportModel automatically creates a graph for each table in the drill-down report. In this case, the TableAdaptor of the table interface must be passed for display to TableGraph. The other way of creating a graph is through the ReportGraphSpecs, which makes a graph based on an ElementSpec.
SummaryReportModel needs a QueryObject which will provide the view on the summary data. Similarly, DetailedTable needs QueryObject and QueryDescription with which the most detailed row-by-row data of tables can be obtained. QueryDescription determines the type of DetailedTable that is to be opened.
16
(ReportValues) QueriesHolder
ReportDetailedTableSpecs
Figure 17 shows a structural diagram of ReportValues. It shows a detailed structure of the objects that ReportValues needs. It first needs the FMState in order to pass around the information. The queries are built up using QueryObjects for each query needed. The ElementSpecs can point to a SingleElementSpec or a CompositeElementSpec. SingleElementSpec makes its results by directly putting constraints on the values returned from a QueryObject. CompositeElementSpec, on the other hand, is an arithmetic function on two other ElementSpecs. The specification of the reports are stored in the following manner. Each report, in ReportInterfaceSpec, consists of a label, window-level formats, such as the specification of the functional columns, and the specifications of the tables. It also has a total value. The total value is a RowInterfaceSpec. It indicates the total value of the entire report. This total value is needed when an arithmetic operation of two reports is performed. This is basically the arithmetic operation of the the two total values. The TableInterfaceSpec is similar to the ReportInterfaceSpec in having its own total value. The functional column specifications are passed down to this object. But it points to a collection of RowInterfaceSpecs. Each RowInterfaceSpec actually holds the BlockValues that are inserted into the cells of the tables. It makes the BlockValues based on the result of the ElementSpecs. It inserts the values for the functional columns based on the specifications. It can also be tied to an action that is executed when the cell or row is double-clicked.
17
ReportSpec Label Total Function column spec Table specs Window display format
QueryObject
ValueModel
CompositeElementSpec ReportValues FMState Queries ElementSpecs ReportWindowSpecs Menu GraphSpecs DetailedTableSpecs SummaryReportSpecs Name Element1 Element2 Operator Result
RowSpec element spec Function column spec Double-click function element results
BlockValues
18
19
4.2 Business Logic and GUI Specification Data Model Business Logic and GUI Specification Data Model
Application_Editor application editor_name
Report_Detailed_Table_Specs application (FK) editor_name (FK) spec_name window_label without_fields displayer_class type original_table error_table no_edit_fields query_name menu_label
Report_Summary_Specs application (FK) editor_name (FK) spec_name query_name window_label field_types alignments groupby_columns summing_columns calculated_columns formats display_columns
Report_Graph_Specs application (FK) editor_name (FK) spec_name selections spec format column_labels window_label
Figure 18 - Business Logic and GUI Data Model The data model that contains the descriptive data (meta-data) needed to build a financial model is called the Business Logic and GUI Data Model. The foreign key relationship are shown in Figure 18 - Business Logic and GUI Data Model. Figure 19 depicts the entity relationships. To build a GUI with a given report element requires information detailing the look and feel of the GUI as well as information regarding how the data is to be displayed. Report_Query_Specs holds the queries used to retrieve data from the financial database for all the report elements. Report_Detailed_Specs stores the data necessary for building a table based report. Report_Summary_Specs stores the data necessary for building a summary report. Both it and Report_Detailed_Specs have a query_name field which relates them to Report_Query_Specs. This provides the corresponding report elements with means to retrieve the data they are to display. Report_Graph_Specs stores data for building graph reports, but it does not have a reference to Report_Query_Specs. Rather it is associated with Report_Element_Specs which contains the information needed to get the query from Report_Query_Specs.
Report_Composite_Window_Specs contains information for putting one or more report windows together. Report_Window_Specs data specifies how to build a report window. A report window contains one or more element specs found in Report_Element_Specs. Report windows also have menus which are defined by Report_Menu_Specs. Report_Menu_Specs contains data for building a menu. Each menu item is associated with a detailed table report, graph report, summary report, or another menu. Selection_Spec has the data for building a selection criteria box. It references the data in Report_Query_Specs necessary for specifying its queries. Selection_Spec also has data referenced by Report_Query_Specs to augment the query specification in Report_Query_Specs.
Report_Composite_Window_Specs
FM_State_Formulas
Report_Window_Specs
Report_Column_Specs
0,2
0,1 Report_Detailed_Table_Specs
0,1 Report_Summary_Specs
0,1 Report_Graph_Specs
Report_Query_Specs
0,1 Selection_Spec
21
1. 2.
QueriesHolder holds a collection of associations mapping query names to queries and their results. ElementSpecs holds a collection of associations mapping names to selection specs. For building the report window, two types of selection specs are available. It always holds query selections specs called total. They should represent the total value of the report. The total is currently being used by the DuPontModel. a) SingleElementSpec returns the sum of all the rows that satisfy the given constraints. It returns a block value which returns the desired sum when evaluated. It holds the following specifications. i) Spec name. ii) The name of the query value, which it obtains from the QueriesHolder. iii) The selection constraints that determine which rows of the result to choose. iv) The specification for calculating the value of each row. The specification basically involves arithmetic operations on the columns of the row that hold numbers. b) CompositeElementSpec returns the result of an arithmetic operation on two other selection specs. This spec is indirectly dependent on the query values. It holds the two ElementSpecs and the operator. The second operand can also be a number or a symbol that stands for a method call to the ReportValues object that holds the element spec.
II. Specifying the report interface. ReportSpecsHolder keeps a collection of associations mapping report names to the report interface specifications, called report specs. The interface also has a menu associated with it. More than one interface can be specified, but there should always be a default interface. The report interfaces look is basically a collection of tables lined up either horizontally or vertically, each with a specified set of columns and rows. All tables of a given report have the same number of columns. The tables specify the rows, which in turn hold the values that are to be put into the table cells. Instead of inserting numbers, value models (more specifically BlockValues) are inserted so that when the results of the queries change, the cells obtain the new values automatically. 1. The report specs hold the following information. a) Report label. This label is used if the report is displayed as a window. b) Function column spec. There are columns that are dependent on the query values, and there are also function columns, which are functions of other columns. The arithmetic function for each of the function columns must be specified. The query specification for the query-based columns is not necessary at this level because the specifications of these columns are assumed to be constant throughout all the report specs. Each function column needs to specify two functions, one for a cost table and another for a profit table. The report spec picks the desired one for each table (each table spec should do this). c) A collection of table specs. d) The total value of the totals of the table specs. The default is to sum up the table totals, but it can be changed. Also a total table can be displayed below all other tables if desired. e) Display format. The values can be displayed after being divided by an integer value. The table specs hold the following information. They correspond to the tables of a report. a) Table label. This label can be displayed if desired. 22
2.
3.
b) Function column spec. This spec is obtained from the parent report spec. c) A collection of row specs. d) The total value of the row specs. The row specs, which correspond to the rows of a table, hold the following information. a) Function column spec, obtained from the parent table spec. b) An array that is specifies the action when the row is double-clicked. c) A formula for obtaining the values. The formula is an arithmetic specification of ElementSpecs and operators. Instead of obtaining values directly from the ElementSpecs, it is also possible to obtain values from other row, table, or window specs. d) A collection of value models (more specifically block values), corresponding to each column. They are obtained by using the formula and are inserted into each cell of a row in the report interface.
III. Specifying the graphs. I. I. I. Specifying the detailed table information. Specifying the summary reports. Specifying the menu of the window interface. The actions for opening graphs, detailed information, and summary reports will be inserted there.
Using ReportValues
In order to use the report specs, you must know the queries needed and the desired view of the report interface. 1. 1. 1. 1. It is recommended that you first determine the database tables and queries needed. Then determine the optimal split between the queries and the query value selections. Then determine the look of the report interface. Determine what value each cell of the tables will hold. Then determine the other specifications. From these specifications of (3), create the menu specs. Also insert double-clicking actions into the cells of the tables if desired.
We have developed GUIs to allow the application developer to easily specify all of the above.
23
4.4 ValueModel
We usually think of values as being the attributes of objects, or sometimes we think of them as being special classes. For example, an Employee object will have attributes like salary and hiring date, and these values will be instances of classes like Money or Date, which we might consider a value class. But there are other ways that objects can represent values. VisualWorks has a class called ValueModel that represents a single value. Not only can clients of a ValueModel read and (usually) write its value, they can become its dependents and be notified when it changes. GUI widgets usually depend on a single ValueModel. So, if an Employee object stores its salary in a ValueModel then a text widget can depend on the salary and be notified when it changes. The most common ValueModel is a ValueHolder, which is just a container of a value. Instead of storing its attribute in an instance variable, an object can store its attribute in a ValueHolder, which can be stored in an instance variable. A read or a write to the instance variable must then get converted to a message to the ValueHolder. This lets clients depend on the attribute and be notified when it changes. Most other ValueModels are adapters. For example, a date adapter converts a value that is a date to a value that is a string. Thus, a date adapter might translate between a text widget, which expects a string, and a ValueHolder containing a date. The most interesting ValueModels are ComputedValues, which define one value in terms of others. ComputedValues are often defined as a function of other ValueModels and as such use the dependents feature of ValueModels to stay up-to-date with the other ValueModels. There are many items that can be based on other values. For example, value PROFIT is really a function based on the amount of total SALES minus the total COSTS; whenever SALES or COSTS change so does PROFIT. The PROFIT value is represented by a BlockValue which is a specialization of ComputedValue that calculates its function based on a Smalltalk block. Whenever the value is needed the block is evaluated. In addition to BlockValues who compute their functions through Smalltalk blocks, there are also QueryValues which compute their values from queries. This allows the model to be directly hooked into the database without the need of writing specific code to transfer values from queries to ValueModels. The inheritance diagram for the ValueModels is shown in Error! Reference source not found.. Although the actual VisualWorks ValueModel hierarchy has several additional classes, only the important ones for the framework are shown. The default protocol for ValueModel is very small. It only contains the value message to return its value. But since many ValueModels are also used in formulas by ComputedValues, it should be easy to combine them to form the formulas. We added methods for arithmetic functions like + and - to ValueModel that automatically create a ComputedValue. The result is that instead of creating a BlockValue for PROFIT with code such as: BlockValue block: [:sales :costs | sales - costs] arguments: (Array with: salesHolder with: costsHolder) we can define the profit as "salesHolder - costsHolder". The definition of - in ValueModel is aValue ^BlockValue block: [:x :y | x - y] arguments: (Array with: self with: aValue)
24
We added to ValueModel all of the basic arithmetic operations and a few for operations for string and date manipulation. As a result, it is easy to define new ValueModels based on other ValueModels.
9DOXH0RGHO
value +, -, *, /
dependents
UI Widgets
value value:
9DOXH+ROGHU
&RPSXWHG9DOXH
eagerEvaluation:
block
%ORFN9DOXH
query
4XHU\9DOXH
ValueHolders have a direct reference to their value, and as a result have a value: method to set this value. This message is mainly used by interface widgets, but can be used programmatically to change the value. ComputedValues also add a few messages to the basic ValueModel protocol that determine how it computes its value. The value can be computed eagerly or on demand by sending the eagerEvaluation: message. Values which are associated with queries turn-off eager evaluation since queries can take seconds to compute. Both BlockValue and QueryValue only extend ComputedValues interface by adding messages to initialize their blocks and queries.
4.5 Queries
Not all information for an application will be stored in memory. Instead, this information is stored externally in a database, and values are fetched by querying the database. For example, consider a payroll system. There might be one function that lists the number of hours worked by an employee during a time interval. For such a system, there would be an interface that allows the user to enter the employee id and date range. Once they are entered, the database would be queried for the number of hours worked. Relational databases have their own language for specifying queries. Many times the language is SQL. For our application to query a SQL database, it must send its commands as SQL statements. A default SQL statement might look like: SELECT fields to return FROM tables in query WHERE clause to select GROUP BY fields to group on ORDER BY fields to sort on
25
The WHERE, GROUP BY, and ORDER BY parts of the statement are optional. For our hours worked example above, we would have an SQL statement such as: SELECT SUM(hours) FROM time_cards WHERE employee_id = 12345 AND date < 1/1/98 AND date >= 1/1/97 While we could model each query as a string, many queries have similar parts and these parts might change over time. For example, we might have several queries that have the same WHERE clause that specifies that the records returned should be within a date range. If we needed to change the condition to add another condition, we would need to change all the strings in the code. Clearly, this is undesirable. Another way to model the queries might be to make an object that holds each query part as a string and then concatenates them together when we execute the query, but we would like to include other Smalltalk objects besides strings in our expressions. Instead of constructing a string from code like: orderNumber = , orderNumberHolder value printString, we would rather construct the SQL expression from code like: salesTable orderNumber = orderNumberHolder. When the query is evaluated the expression is turned into the appropriate SQL statement string. Otherwise, we must update the string whenever the orderNumberHolder ValueModel changes. Instead of using strings to model the queries, we chose QueryObjects to model queries and QueryExpressions to model the individual expressions (e.g., WHERE clauses, GROUP BY clauses, etc.). QueryObjects then construct their SQL statements at runtime using the QueryExpressions. A query returns something that behave like a table; it has rows that are separated into fields. Many databases even allow you to create database views from a query. These views can then be used in other queries as if they were real tables. We want to have a similar feature in our QueryObjects, but instead of having to create database views for each query, we want to be able to use QueryObjects in other QueryObjects. The most primitive type of QueryObject is a TableQuery. TableQueries represent tables in the database, and are the basic building blocks for all other queries. They correspond to the tables listed in the FROM clause of a SQL statement. Evaluating a TableQuery by itself just returns all the records in the table. Whenever multiple tables are listed in the FROM clause of a SQL statement, they are joined together. This operation is represented by a JoinQuery. JoinQueries join two QueryObjects to form one QueryObject. The other clauses of a SQL query are also QueryObjects. For the SELECT part, we use a ProjectionQuery since the SELECT part tells the database what fields to project in the result. The WHERE clause is modeled by a SelectionQuery since it tells the database which rows to select. The ORDER BY and GROUP BY clauses are represented by OrderQuery and GroupQuery respectively. Since all of these queries also have expressions, they have QueryExpressions that will create their SQL code for their respective clauses. In addition to the SQL syntax described above, there is an additional keyword that can appear in a SELECT statement. The DISTINCT keyword specifies that all records returned by the query should be unique. This is modeled in our system by a DistinctQuery which wraps another query and returns only the unique rows. There are a couple additional QueryObjects that dont have a direct SQL mapping. A RenamingQuery renames the fields of another query. This is useful for achieving consistency with the field names. An ImmediateQuery evaluates and caches the results of its wrapped query. Instead of letting the database compute the values for the overall query, ImmediateQueries signify that part of the calculation should be performed in Smalltalk. These can be used for performance optimizations and also when values from one database must be merged with values from another database. Since ImmediateQueries signify that part of the query calculation should be performed in Smalltalk, we can present a unified query model that can straddle several databases without the developer needing to write special code.
26
ProjectionQuery query
time_cards
Figure 21 - Dynamic structure of QueryObjects A single SQL statement is represented by a set of QueryObjects. The SQL statement above is shown using QueryObjects in Error! Reference source not found.. Both the SelectionQuery and the ProjectionQuery also have QueryExpressions which are not shown. Figure 22 shows the QueryObjects object diagram. The query operations have been split-out under a WrapperQuery which defines some common behavior for all operational queries. Also, the queries that need a QueryExpression have been further split-out under ExpressionWrapperQuery.
QueryObjects support a protocol to retrieve values from the database through the value, valueIfAbsent:, values, and valuesAsObject messages. Both the value and valueIfAbsent: messages expect to return zero or one row from the database whereas the values and valuesAsObjects can return zero or more rows. If value or valueIfAbsent: query returns more than one row, then an error is raised. The valuesAsObjects message is used when you wish to return the values from the query as Smalltalk data model objects, and not as arrays.
4XHU\2EMHFW
dependents
4XHU\9DOXH
leftQuery rightQuery
-RLQ4XHU\
7DEOH4XHU\
:UDSSHU4XHU\
tableName fieldNames
query
5HQDPLQJ4XHU\
'LVWLQFW4XHU\
([SUHVVLRQ4XHU\
,PPHGLDWH4XHU\
expression isDistinct
values
2UGHU4XHU\
*URXS4XHU\
6HOHFWLRQ4XHU\
3URMHFW4XHU\
orderByBlock
groupByBlock
selectBlock
answerBlock
4XHU\([S
valueUsingMapping:
dependents
4XHU\2EMHFW
9DOXH4(
value
valueUsingMapping:
)LHOG4(
field
valueUsingMapping:
0HVVDJH4(
selector
valueUsingMapping:
receiver arguments
expression
5HQDPHG)4(
valueUsingMapping:
Figure 23 - QueryExpression's object diagram In addition to the value retrieval protocol, there are also methods that return fields from the query so that they can be used to create QueryExpressions. There are two main methods that are used for this support: @@ and fieldNames. The @@ message returns a QueryExpression that represents the field for argument name, and the fieldNames message returns the list of field names that are available to the query. There is also several "helper" methods that are defined by QueryObjects. These methods allow you to create new QueryObjects based on the receiver. For example, you can join two query objects together by using the join: message. In addition to the public protocol for retrieving values, creating QueryExpression, and creating new QueryObjects, there is also a private protocol for converting the QueryObjects into SQL by interpreting them. The main method that builds the query is the buildQuery Template Method in QueryObject. It uses the answerBlock, selectBlock, orderByBlock, and groupByBlock methods to help build the query. Each of these build specific parts of the query.
4.6 QueryExpressions
As mentioned in the previous section, QueryExpressions specify the expressions for the different parts of the SQL query. A query such as SELECT employee_id, SUM(hours) FROM time_cards WHERE (date < 1/1/98) AND (date >= 1/1/97) GROUP BY employee_id ORDER BY employee_id has four expressions (the FROM line is formed from JoinQueries not expressions). Looking at each expression closely we see that they are almost in a Smalltalk syntax. Renaming a few of the logical operators to their Smalltalk equivalent (e.g., AND &), we can convert everything except for the functions. Functions with one argument are easily converted to unary messages, and functions with more arguments are converted to keyword messages. Once we convert the functions into messages, we see that each expression is a series of message sends to a field in a table. Therefore, we can represent each expression as a parse tree of message and field nodes. Since queries can also refer to constant values, we also need parse nodes for constant values. These nodes can either hold a constant such as 100, or hold a ValueModel which holds the constant. If the value node holds a ValueModel, then when the query is evaluated, the current value of the ValueModel is used. 28
Error! Reference source not found. shows the object diagram for QueryExpressions. In addition to the three types of parse nodes, there is also a RenamedFieldQueryExpression class that is used together with the RenamingQuery. Since each field of the answer of a RenamingQuery can refer to many fields of its wrapped query, we need a reference to the expression that created that field. A RenamedFieldExpressionQuery holds onto the original expression for the renamed field. For example, given the query above, we might want to rename the fields of the answer to be employee_id and hours_worked. For such a query we would need two ReanmedFQEs one for the employee_id expression and one for SUM(hours) expression. As an example of the runtime configuration of the QueryExpressions, Error! Reference source not found. shows the expression for the WHERE clause (i.e., the expression that is used by the SelectionQuery). There are three different protocols for QueryExpressions. One is used for easily forming the expressions. It consists mainly of a redefinition of the doesNotUnderstand: message. This makes it easy to construct the parse trees simply by executing Smalltalk code. Whenever the doesNotUnderstand: message is received, the QueryExpression constructs a MessageQueryExpression with itself as the receiver. Although the doesNotUnderstand: mechanism can handle most messages, there are a few that must be overridden since they are defined by Object (e.g., isNil). Another protocol is responsible for converting the expression into SQL code. Although we could generate our own SQL code, we rely on the VisualWorks Lens framework to generate it for us. Since we use the Lens framework, this protocol consists of only one message: valueUsingMapping:. This returns the Lens object that is equivalent to the expression, since the blocks used in the Lens queries are similar to our QueryExpression, the valueUsingMapping: method simply evaluates the QueryExpression in the context needed by the Lens blocks. The final protocol supports the Observer pattern. Since QueryExpressions can also have ValueModels, they need to update their dependents when they change. These dependents can either be other QueryExpressions or QueryObjects. Whenever an expression changes, the query that it is contained in must be re-computed.
SelectionCriterion is an object connecting queries and a user interface for specifying constraints.
4.7.1 Example
We consider an example from the Aurora financial model application (see Figure 25). In the application users select a list of product families, for which they want to view the data, the period of time they are interested in, and, possibly, the kind of records(internal sales, effect of internal sales).
The selections a user can make map to value models within the model of the interface, SelectionCriterion. In this case we have the following value models: familyList isInternalSales isEffectOfInternalSales startingDate endingDate
4.7.2 Implementation
A usual way of implementing SelectionCriterion is to have one instance variable for each of the value models. However, this approach requires a new class to be created for each new selection interface. Instead, we would like to have one SelectionCriterion class to work for every selection interface. Therefore, we use a dictionary of the value holders as an instance variable in SelectionCriterion. In the dictionary each
30
value holder is assigned a name(key in the dictionary). The name is then used for accessing the corresponding value holder(see examples in Specifying Selection Criterion). Since the value holders are value models, they can be used in query expressions. The query expressions will be then dependent on the value holders. The queries that use the query expressions will also depend on the value holders, and, hence, be recalculated whenever the value holders change.
31
As shown, an instance of SelectionCriterion has a dictionary of value holders(selections). A key in the dictionary is the name of the corresponding value holder. The key is also the name of the method called to
Figure 27 - SelectionCriterion Structure access the value holder. For example, to access value holder whose key in the dictionary is "familyList", one simply calls selectionCriterion familyList, where selectionCriterion is an instance of the SelectionCriterion class. The class of a selection held by a value holder as well as its initial value at the time of financial application startup is specified using SelectionCriterionEditor. A view of SelectionCriterionEditor is shown below.
32
There are several conventions for specifying the initial value in SelectionCriterionEditor. 1. If the type of the value is primitive (Number, Boolean, String, Symbol), the initial value is to be entered in the input field. For example, false is entered for the selection isInternalSales whose type is Boolean. If the type of the value is Timestamp, the initial value is specified by the name of an initialization method on the class side of the Timestamp class. For example, entering yearStart for the initial value of the startingDate selection specifies that "Timestamp yearStart" will return the initial value for the startingDate selection. In other cases, it is assumed that the type of a selection is a kind of Collection. That is, it needs to be initialized with a list. This is done by specifying in the initial value field the name of a query stored in the ReportQuerySpecs table. At the system startup, the query will be executed and the corresponding selection will be initialized with its results. For example, we specify familyQuery as the initial value for the familyList selection.
2.
3.
The queries referenced as initial values are specified declaratively using the query model editor. The query model editor provides an interface for constructing complex queries from simpler ones. The queries are then stored in the database and retrieved as need for them arises. Since queries comprise a significant part of business logic, such treatment makes it possible to modify and construct new business models while preserving application code intact.
33
4.9 FMState
ReportValues often need access to global information about other ReportValues. These objects keep this information accessible by keeping a reference to a FMState object.
The state object is created by the security module when all of the security checks have passed correctly. The state is then passed to the startup window (DuPontModel, FMEditor, etc.). The startup window passes the state the each drill-down, and each drill-down passes it to any window it creates. That ensures that window will have the state information, if needed. A FMState holds a variety of types of information. To keep the information more manageable, it is stored in four different namespaces. The namespaces are values, selectionBox, windows, and applicationInfo. values: This is where the business logic is cached. Although values is actually a dictionary, it is the default namespace for a FMState. For example, state netSalesValues will search for #netSalesValues in the values dictionary. This trick uses Smalltalks doesNotUnderstand: mechanism and greatly improves code readability, but is not necessary part of an FMState implentation. windows: This keeps a list of all windows currently open for that session. These windows are listed in under the Windows menu of a CatModelWrapper. This lets the user easily just between windows of the same running application. applicationInfo: This stores the ApplicationInfo object selected in the CatLoginDialog. selectionBox: This stores the SelectionCriterion object for this states session.
4.10 ApplicationInfo
Not all of the applications description can be put in the database. The data which tells how to setup security is needed before a connection to the database has been made. Also the location of the database and the name of the data model are needed to make the connection to the database. Finally, if something goes wrong, the user will need to know the system administrators name and phone number. This data is stored in an ApplicationInfo. In the CatLoginDialog, the user selects which ApplicationInfo to use. This startup data is loaded from a configuration file stored on disk. This file is created by the system administrator through the SecurityAdmin tools, and it is encrypted to prevent malicious users from tampering with the file by hand. During the login process the CatLogin security module store additional important information in the ApplicationInfo. Examples include a QueryDataManager, the users list of editable families, and the users login name. After the login process the ApplicationInfo is passed to the FMState for future access. ApplicationInfos values are set up as a namespace so the code state applicationInfo username looks up #username in the the ApplicationInfos values
4.11 Sessions
Sessions are used to hide data from many simultaneously running applications while sharing the data among many objects in one other application. This is achieved by passing a reference of the session object to every new object in the same session which might need it. In the financial model, FMState objects serve as session objects Using the state in this way involves some tradeoffs. Drawbacks:
34
The code is more complex because the session must be passed around to each object that is created instead of having the code refer to a global location. Passing the whole session around means some objects have access to extra information which they do not need. Benefits: The user can run multiple applications simultaneously. This is achieved because the global information for a running application is always stored locally. This allows each running application to have its own private global information, shared throughout that application. The user can have multiple sessions of the same application running simultaneously. Each has independent, local data. Passing the whole session simplified the interface between classes. Otherwise, each value that is need by a new object, plus the each value needed by objects which the new object will create, have to be passed individually to the new object. In the financial model, a session is created whenever a user successfully logs in for particular application. A user can open multiple sessions for the same application by specifying a new SelectionCriterion. A new FMState will be built for the new selection and the old states ApplicationInfo. The windows for the new FMState will be empty and its values will be re-queried from the database. This way, the new FMState holds all of the data for the new session. A user can also open multiple sessions for different applications simply by going through CatLogin again. Session pattern in the financial model some pitfalls which are not necessarily drawbacks. They are just things to be careful about when applying the pattern. Since classes like QueryObject are application independent, they should not be constrained by adding a state instance variable. If information from the states ApplicationInfo is needed, then that information must be made truly global. Since this information is normally only used when saving query specs to the database, this causes the restriction of specifying only one application at a time. An alternative solution is to make an application specific extension which takes the necessary information as arguments. In any case, the QueryObjects must be created specifically for the QueryDataManager stored in the applications state. This means the creator must know the current session and must call a different instantiation for the QueryObjects.
4.12 Namespaces
Namespaces are used to separate information. Typically, a namespace will hold a set of information that has the same type, is used together, or is created by the same object. Namespaces are an organizational tool that put conceptual walls between objects which might be indistinguishable or otherwise confusing if stored together. Sometimes namespaces simply prevent a naming conflict so multiple, unique objects can share the same base name. For example, NetSales could refer to a window, a query, or a set of values, depending on which namespace is searched. This is achieved by storing the values in separate dictionaries. Optionally doesNotUnderstand: can be redefined. There are several tradeoffs with this technique. Drawbacks: - The code is misleading. In the example below, in appears that the ApplicationInfo has a username: method, when actually doesNotUnderstand: is actually catching the exception. - Its not immediately clear which values will be put in a namespace. This information is clear when instance variables are used. - There is no guarantee that only relevant items are put in the namespsace. - doesNotUnderstand: incurs a minimal performance overhead. The performance is most likely too small to be an issue, however.
35
- Items which have names equivalent to important system messages cannot be put in a namespace unless values at:put: is explicitly used. Benefits: - The code is much more readable. - All of the drawbacks can be avoided by using a dictionary without redefining Smalltalks doesNotUnderstand: for the namespace object. - The code is more flexible. If more information needs to be stored, it can be put in a namespace without writing new code for the object holding the namespace. This single benefit is the principle reason for using this pattern. Namespaces are the solution for a flexiable, dynamically changing system in which many values have to managed. In the financial model, a FMState holds four namespaces: values, windows, applicationInfo, and selection. Each namespace is implemented as a dictionary. Undefined messages sent to the object which hold the namespace are forwarded to the dictionary. This makes the code more readable (state applicationInfo username: jack instead of state applicationInfo values at: #username put: jack).
1. 1. 1. 1.
Create a dependency between the graph and the collection, so that when the collections values change, the graph automatically updates itself. Pass an entire table instead of a collection of values, in which case the dependency between the table and the graph is set up automatically. Display the results of a query in a graph. Again, the dependency between the query and the graph is set up automatically. Display the results of a query for each individual month. The dependency is set up automatically.
Several classes handle the graphing framework. TableGraph handles the graph display. It is able to handle the first two features listed above. This class holds another class called GraphHolder as a subcanvas, which in turn holds the VisualWorks graphics view. TableGraph makes a dynamic version of the VisualWorks graphics package. Because the package requires the specifications of legend, type of graph, legend placement, among other things, to be determined as part of the spec, the specifications cannot change. TableGraph allows all these features to be changed at run time.
QueryGraph is a subclass of TableGraph . It displays the graphs that are calculated through GraphMaker, which makes a graph that is dependent on element specs, which in turn are dependent on queries. GraphMaker handles the last two features above. The GraphMaker holds a two-dimensional collection of block values to display. It is also possible to perform simple arithmetic operations on GraphMaker. The values of the two GraphMakers must have the same dimensions
Its subclass, SingleGraphMaker, gets the value from the result of a set of element specs. The resulting values of each element spec is on the X-axis. Each element spec should return a group of values. The group should match the Y-axis. MonthlyGraphMaker is a subclass of SingleGraphMaker that must use one element spec whose value returns the date of each row along with the value to graph. Based on the current selections of date in CatState, it calculates the values for each month. The X-axis is ordered by the months. CompositeGraphMaker is the result of applying arithmetic operations on GraphMaker.
DetailedTable displays the rows returned from a query. It actually has all the methods for row editing as well, but they are turned off by default. It does not query all the rows at once, but more rows are obtained as the scrollbar is pulled down. The user can specify the number of rows to return. The information that the detailed table uses is passed through a class called QueryDescription.
The subclasses tend to be somewhat query specific. Each one assumes that certain fields exist in the query. IncurrenceRatesTable is used for incurrence rates tables. It allows the rows to be edited. EditableDetailedTable, on the other hand, is a more general class for editing rows of tables. SimpleErrorsTable, on the other hand, is more extensive because it not only edits the original table, but it also creates a row in the error table corresponding to the original table. It is assumed that the error table has at least all the fields of the original table. DialogErrorsTable is even more extensive because it requires the user to enter some information which will be stored in the error table along with the original row information. ErrorCorrectionTable does the reverse of DialogErrorsTable by displaying an error table, and when a row is 37
edited, the error row is deleted, and the edited row is written to the non-error table. The error table's fields must have all of the fields of the non-error table.
PrintFileInterface is a standard print dialog that is opened when the end-user wants to print something. It collects some of the basic information from the user about page-numbering, header, footer, orientation and then calls PrintFile to print the view. PrintFile does the printing work. It takes the model requested to print, the page orientation, the print medium, the title, the footer, the report date, and possibly disclaimer and filename for printing. PrintFile then initializes everything and prints on the specified graphics context which could be a printer device or file
Aside from the TestObject, TestData subclasses, and TestCriterion, there are several support classes: TestSelectionDialog, EqualityTestInfo, TestResultViewer. They are usedfor selecting tests from a TestData collection, storing test result information, and viewing test results, respectively. See each class for detailed descriptions.
5. Security Module
The security module follows some specified requirements to restrict access to the financial data. Different applications could have different security requirements, so the security modules was designed to make it easy to plug in additional security checks and easy to turn some security features on and off. The default security checks include forcing the user to enter a new password after a certain period of time and disabling access from a machine or account after a certain number of login. After passing the active security checks, the security module starts the process of extracting all of the information from the database and organizing it into independent sessions.
1.
5.2 Components
FMLogin manages the security and login process.
Several user interfaces for system administration and user login have been designed with security in mind. They are in the CAT-SecurityGUI category. ChangePasswordDialog, NewUserDialog, FMLoginDialog, ValidNodesDialog, and UserPropertiesDialog are some examples of security support user interfaces. Most are used with the SecuirtyAdmin tool or during the FMLogin Process. A FMState is created at the end of the login process. It serves as the basis for separating sessions and sharing data among a sessions ReportValues. The ApplicationInfo class stores all of the information necessary to configure the security process, connect to the database, and start the application. It also includes some extra information such as the name and phone number of the system administrator. Because this information is needed before a connection is made to the database, it is persistently stored in .cfg files in a specific configuration file directory. The Cryptor prevents users from changing ApplicationInfo configuration files and security tables by hand. It has encrypt: and decrypt: methods which take a string as input and return encoded and decoded strings, respectively. Using this class forces administrators to use the Administrator Application to make changes. Several database tables have been added to the reusable part of the data model to persistently store user and machine specific information related to security. They are: Accessible_Products, Editable_Products, Old_Passwords, Cat_User_Prof, and Valid_Nodes.
1.
1. 1.
1.
1.
1. 1.
39
current time is stored in the - column. The machine will be automatically re-enabled after a specified elapsed time.
40
41
Figure 31 - UserPropertiesDialog
FMLogin first locks itself as a critical section. Only one FMLogin security verification process is permitted at a time. After the security verification has completed (successfully or unsuccessfully), another login can be attempted. The process then proceeds to a login failure loop, other security and the financial model startup routines.
42
Lock
failed
halt
Other Security
ok
failed
Startup
Unlock
done
Figure 33 - FMLoginDialog
43
Initially, the user sees a dialog window for logging in (FMLoginDialog). The Application is the name of the ApplicationInfo configuration file to load. Many applications could support a production and a test database, so easy access to two databases is provided in the login dialog. The user must also type in a valid user id and password.
abort
halt
cancel
Login Window
ok
Application Setup
ok
abort
Admin Recovery
abort
ok
Figure 34 - Login Failure Loop After entering this information, FMLogin attempts to setup the system and login with the username and password. After three consecutive failures, the login process aborts immediately.
44
missing
Find database
found
abort
ok
disabled
Node security
ok
Profile security
ok
disabled
abort
Role security
ok
fails
not updated
ok
45
Application setup read a .cfg file from the config directory and stores the information in an ApplicatoinInfo. Then it verifies that some tables exist in the database. If the databases data model has changed, it will rebuild the clients data model to match .At this point, the user has a successful database connection. During the next stage of the login process, FMLogin tries employs other security techniques to valid the user before giving them full access to the financial model. The ApplicationInfo has a parameter which determines which checks are performed
no
valid node
yes
abort
hasnt passed
enabled node
yes
disabled time
has passed
ok
ok
re-enable node
Figure 37 - Node security Node security ensures only designated computers can keep a connection to the database. (A node is an IP address). This check is done by first retrieving the record for node from Valid_Nodes database table. If the node is not in the table the login process is aborted. If the retrieved records enabled column is false, the disabled time is checked. The node can be re-enabled if enough time has elapsed since the disabled time. This has the advantage of providing disrupting a hackers attempts while not necessarily forcing a system administrator from intervening to re-enable a node. If not enough time has passed, abort the login process. When a successful login occurs, login_failures is reset to 0.
no
profile exists
yes
abort
enabled profile
yes
disabled time
has passed
ok
ok
re-enable profile
46
Profile security is similar to node security except that instead of disabling machines, it disables a users account. The users profile is retrieved from the FM_User_Profile table. Otherwise, this security check behaves exactly like Nodes security.
Role Security
valid role abort
ok 3c
Figure 39 - Role Security Role Security allows different types of users to access different parts of the financial model. Roles are actually implemented by Oracle, but the financial model extends the roles purpose while limiting the roles which actually play a part in security. The four primary roles are: dba, accountant, modeler, and developer. The dba can read, write, and change any data model and can use the SecurityAdmin tools. The developer can read, write, and change any of the data models. The modeler has read and write the business logic and GUI specification data models and can run the FMEditor. The accountant can read the business login and gui specification models and can read and write the business unit specific and security data models. Write privileges are constrained by the application (only personal information in the security model, only editable products in the business unit specific model). The accountant can also run the financial model. Other security checks can readily be added at this point of the login process.
yes
password expired
no
ok
ok
Figure 40 - Password Security If the password has expired, open a ChangePasswordDialog. If the new password is listed for that user in the Old_Passwords table, force the user to select a new password by reopening a ChangePasswordDialog. When the new password is entered add the old password to the Old_Passwords table and set the new password for the user.
47
login completed
Figure 41 - Financial Model Start Up At this point, FMLogin has finished its security checks. Using information from ApplicatoinInfo and a users selected active role, FMLogin creates a FMState passes it the startup class (DuPontModel, FMEditor, or SecurityAdmin), opens the startup class, and unlocks itself.
6. Future Work
There are many extension to the domain-specific visual language that could be added. For example, you might image that you want to be able to reuse tables, element specs, and report values more globally. This would provide for a finer grain of development. Thus, the developer can make a set of ReportsValues used in different applications but associate different menus, calculated columns etc. They could also create queries that can be reused in different ReportValues. Of course there are tradeoffs with this as the developer will have to know more and try to keep track of global information during the design. We also took into consideration that the application could be distributed. We believe that the architecture allows for this, but there may be some needed changes to allow for distributing the business logic correctly, especially if you want to share these and have views automatically updated for multiple users when the business logic or GUI descriptions change. This application has logically and architecturally been developed as a three-tiered application. The current implementation in Smalltalk only used two real tiers since we could easily let the business logic and GUIs live in the same place. However, it would be easy to either use Gemstone or DST and move the ReportValues to a middle-tier.
7. Summary
What we have described here is the architecture and design of a domain-specific visual language for building financial models. There has been many reusable components integrated into the system. The overall architecture is language independent and could be developed using any general purpose language desired. Our architecture was developed around a object-oriented framework written in Smalltalk [Goldberg & Robson 1983]. Smalltalk allowed us to quickly develop working prototypes, and get immediate feedback from our users. Since VisualWorks is robust enough for production use, these prototypes could evolve into production applications.
48
8. Patterns
The following is an incomplete list of the patterns that being used in the Financial Modeling Framework. All of the Reports patterns by Brant and Yoder Sessions/Namespaces patterns by UoI to be developed Adapter by GOF BETWEEN VALUES AND QUERY OBJECTS Builder by GOF REPORT VALUES BUILD QUERIES AND REPORTS AND VALUE-MODELS Command by GOF QUERY OBJECTS ARE SOMEWHAT COMMANDS Composite by GOF QUERY OBJECTS and POSSIBLY THE GUIs Decorator by GOF QUERY OBJECTS Factory Method by GOF REPORT VALUES Interpreter by GOF REPORT VALUES AND QUERY OBJECT Observer by GOF QUERY OBJECTS Singleton by GOF DONE BY STATE SOMEWHAT...SINGLE ACTIVE STATE OBJECT and a SINGLE ACTIVE SECURITY MODULE Patterns by Kent Beck -Used throughout....just good smalltalk patterns Template Method by GOF QUERY OBJECTS REPORTVALUES Visitor by GOF DuPont Model to build code and write to database....walks through interface widgets. Constraints by Johnson USED IN THE VALUEMODELS AND QUERY OBJECTS Evolution, Architecture, and Metamorphosis patterns by Foote and Yoder Some of the Selfish Class patterns by Foote and Yoder Evolving Frameworks: A Pattern Language for Developing Object-Oriented Frameworks Authors: Don Roberts and Ralph Johnson, University of Illinois USED DURING THE DESIGN AND DEVELOPMENT OF THE SYSTEM Checks by Ward Cunningham I believe we use patterns 1-6 of his paper. Understanding ValueModels by Bobby Woolf Null Object by Bobby Woolf and Ralph Johnson USE FOR NULLREPORTVALUES Stars: A Pattern Language for Query Optimized Schema by Steve Peterson are patterns that we did use in our data modeling of the business. We really dont describe that in this paper but it was done and might be interesting to note as a side-point especially when we talk about designing a database for the company. Ward Cunningham. The WyCash Report Writer, OOPSLA 92 Workshop, Towards an Architecture Handbook. http://c2.com/doc/ooplsa91.html DOING SIMILAR THINGS IN OUR SUMMARYREPORTMODEL
49
9. References
[Brown & Whitenack 95] Kyle Brown and Bruce G. Whitenack. Crossing Chasms - A Pattern Language for Object-RDBMS Integration, PLoP95 Proceedings. Ward Cunningham. The WyCash Report Writer, OOPSLA 92 Workshop, Towards an Architecture Handbook. http://c2.com/doc/ooplsa91.html Brian Foote and Joseph Yoder. Evolution, Architecture, and Metamorphosis, PLoP95 Proceedings. John Brant and Joseph Yoder. Reports PLoP96 Proceedings. Margaret M. Burnett, Adele Goldberg, and Ted G. Lewis. Visual Object Oriented Programming, Concetps and Environments, Manning, 1995. Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, and Michael Stal. Pattern - Oriented Software Architecture, A System Of Patterns, Manning, 1996. Martin Fowler. Analysis Patterns, Reusable Object Models, , Addison-Wesley, 1996. Brian Foote and Joseph Yoder. Attracting Reuse, To appear in PLoP96 Proceedings. Adele Goldberg and David Robson, Smalltalk-80:The Language and its Implementation, Addison-Wesley, Reading, MA, 1983 Eric Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software, AddisonWesley, 1995. Ralph E. Johnson. Documenting Frameworks with Patterns, OOPSLA 92 Proceedings, SIGPLAN Notices, 27(10): 63-76, Vancouver BC, October 1992.
[Cunningham 91]
[BMRSS 96]
[Fowler 97]
[GHJV 95]
[Johnson 92]
The collection of assets constituting the farm have been separated into four categories: Land, Crops, Supplies, and Capital_Goods. Each type of asset has an identifying field, an adjustment date, a quantity, and a value. The identifying field allows for the categorization of the asset types. The adjustment date keeps track of when the quantity or value of an asset has changed. The value field represents the total value invested in all the assets with a given identification field as opposed to the unit value. The complete inventory of all assets is kept in another table called Inventory. All data in Inventory can be accessed on a monthly basis. Any time a transaction occurs involving Land, Crops, Supplies, or Capital_Goods, Inventory is automatically updated. The Supplies_Used table manages the depletion of supplies used in production. All supplies must be directly related to the production of crops. This constraint simplifies handling the cost of using a supply and attributing it to some plot_id. App_date is the date of application and qty specifies the amount of the supply used. App_date provides a means of keeping a history of supply use. Qty is necessary for updating the appropriate asset record and calculating the cost. The Production table is very similar to the Supplies_Used only it keeps track of the amount crops grown on a plot in a given season. Notice that crop_id is not part of the primary key so only one type of crop can be grown on a given plot of land in any one season. This was done to keep the profit analysis based on a plot of land simple. Any asset produced which is not sold becomes part of the inventory resulting in an increase in the quantity field of the corresponding asset record . Income is generated based on the sale of an asset. The Income table handles such transactions. The number of assets sold with a common identification as well as the date of sale and total revenue generated is stored. There are two types of costs modeled. The Period_Costs table stores the data pertaining to a cost which occurs periodically such as taxes. The other type of costs, variable costs, is handled by the Var_Costs table. The only difference in the data stored in the two tables is a quantity field (qty) inthe Var_Costs table. It allows for the purchase of several assets at the same time. Costs can be either production or non-production related. The type field determines which is the case. The dollars field represents the total cost in the case of Var_Costs rather than the cost per qty.
51
Inventory asset_id (FK) inv_date qty value plot harvested Production plot_id prod_date crop_id qty
asset held
crop produced
Supply used
Plot used on Var_Costs asset_id (FK) vcos_date type description qty dollars
Period_Costs asset incurring cost asset_id (FK) pcos_date type description dollars
asset incurring cost Income asset_id (FK) sell_date qty dollars asset sold
Queries may be constrained by selection criteria chosen by the user. If the selection criteria is used, the queries may be constrained by any combination of a crop_id, start_date, and an end_date. Income Queries: Income Generated from a crop_id from start_date to end_date. SELECT sum(dollars) FROM Income WHERE asset_id = crop_id AND sell_date >= start_date AND sell_date <= end_date Income Generated from the sale of Supplies between start_date and end_date: SELECT sum(dollars) FROM Income,Assets WHERE Income.asset_id = Assets.asset_id AND Assets.type = supplies AND Income.sell_date >= start_date AND Income.sell_date <= end_date Similar queries can be made for the sale of Land or Capital_Goods by replacing the Income table with either Land or Capital_Goods.
52
Total Income Generated from all sales between start_date and end_date: SELECT sum(dollars) FROM Income WHERE sell_date >= start_date AND sell_date <= end_date Cost Based Queries: Production Costs from start_date to end_date: SELECT sum(dollars) FROM (SELECT asset_id, vcos_date, type, description, dollars FROM Var_Costs UNION ALL SELECT * FROM Period_Costs) WHERE type = production AND vcos_date >= start_date AND vcos_date <= end_date Non-Production Costs can be found by substituting the comparison of type against production with nonproduction. Supply Costs for a plot of land, plot_id, between dates start_date and end_date: SELECT max(Supplies.adj_date), supplies_Used.qty/Supplies.qty*Supplies.value FROM Supplies,Supplies_Used WHERE Supplies.supply_id = Supplies_Used.supply_id AND Supplies.adj_date <= Supplies_Used.app_date AND Supplies_Used.plot_id = plot_id GROUP BY Supplies.supply_id
53