|
|
|
|
|
|
Somusar/Software Production Technique[tm]
A Sample Project Francesco Aliverti-Piuri Copyright © 2003-2007 Somusar Updated on: May 7, 2004 |
|
|
|
|
|
|
|
|
|
Unix is a registered trademark in the United States and other countries, licensed exclusively through X/Open Company Limited.
Linux is a registered trademark of Linus Torvalds in the United States and other countries.
Sun, Sun Microsystems, the Sun logo, Solaris, Java, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.
Symbian and all Symbian-based marks and logos are trademarks of Symbian Software Limited.
Apple and Mac OS are registered trademarks of Apple Computer, Inc. in the United States and other countries.
Intel is a registered trademark of Intel Corporation in the United States and other countries.
PowerPC and CICS are registered trademarks of International Business Machines Corporation in the United States and other countries.
Microsoft, Windows, Visual Basic are either trademarks or registered trademarks of Microsoft Corp. in the United States and/or other countries.
Oracle is a registered trademark, and PL/SQL is a trademark of Oracle Corporation.
SAP and ABAP/4 are registered trademarks of SAP AG in Germany and several other countries.
PostScript is a registered trademark of Adobe Systems Incorporated in the United States and/or other countries.
So.mus.ar, the Somusar logo, Somusar/Software Production Technique, Somusar/Software Production Machine, Somusar/Sisendel, Somusar/Tefigel, Somusar/SoProTech, Somusar/SoProMach, Somusar/Software Entity, Somusar/Software Mold, Somusar/Software Mold Kit, Somusar/Software Mold Building, Somusar/Code Generator Building, Somusar/Generator Building, and Somusar/File Generation Scheme are trademarks of so.mus.ar. s.a.s. in Italy, in the European Union, in the United States of America and other countries.
Other trademarks or service marks referenced herein are property of their respective owners.
| Code Examples | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||
| Figures | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||
| Tables | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||
This document describes a sample SoProTech project,
aimed at showing on a small scale the advantages and benefits
provided by the Somusar/Software Production Technique[tm].
The reader should be aware of
SoProTech[tm] concepts, such as Somusar/Software Entities[tm], Somusar/Software Molds[tm], generatable
files, and the Somusar/Software Production Machine[tm], which include the Somusar languages,
namely Somusar/Sisendel[tm] and Somusar/Tefigel[tm]. An overview of these concepts
is provided in booklet
"Somusar/Software Production Technique[tm]: An Introduction
", which also defines the
contents and context of a SoProTech project.
Main objective of the sample project described in the following
chapters has been to apply all main features
of the SoProTech - in terms of both Software Entities and Software Molds - in order
to practically demonstrate how the new approach
of the SoProTech[tm] can bring a significant
increase of productivity, flexibility,
maintainability and consistency
in the field of software development and production.
In particular, three exercises should give a tangible
idea of these benefits, simulating three real-world cases of
requests for changes, change impact analysis, and change
implementation.
The sample project consists of a small number of entities,
in the simplified business context of a generic company,
running projects for their customers; the company employees
are assigned to departments, and grouped in project teams,
lead by a project manager.
A simple diagram of the sample project entities and relationships
is shown in the following illustration.
Figure 1 - Sample project entity/relationships diagram
The next paragraphs describe the project and library entities of the sample project. Project entities are entity files private to one software development project, as opposed to library entities, which are entity files possibly shared across two or more projects.
The contents of the entity files are listed at the end of this document.
The following table shortly describes the eight project entities
of the sample project. Later in the document, in one of the
exercises, a ninth entity (namely, company) will be added to the project.
The entities are divided in four logical
packages, corresponding to subdirectories under the "project"
directory. The logical packages are the following:
| Entity | Location under directory "project" | Description |
|---|---|---|
| customer | ./business/ | A company/organization, its address, and a contact person |
| project | ./business/ | A project within a company, some information about it, a project manager, the involved personnel, a project plan and budget |
| department | ./company/ | A department within a company |
| employee | ./company/ | An employee, some related information, and the department s/he works in |
| address | ./location/ | Address of an organization |
| country | ./location/ | A national country |
| person | ./persons/ | Commercial information about a person, basically name and how to reach him/her |
| person_info | ./persons/ | Private information, to be kept distinct from employee info |
The next table describes the two library entities
of the sample project. The library entity files reside
directly under the "library" directory, which thus does not
contain any logical package.
| Entity | Location under directory "library" | Description |
|---|---|---|
| image | ./ | A photo, an illustration, or a picture |
| strings | ./ | Various types of strings, standardized across the project |
The mold kit of the sample project consists of molds to generate software
in the following languages:
SQL is used for the DB layer, while Java[tm] and C++ are used
for the LOGIC layer.
The table below lists all molds of the sample project,
including molds to generate intermediate files, which
are files not directly required by the project development, but that
are useful as an intermediate step in the software generation process.
| Mold | Description |
|---|---|
| CORE/mold1-.toc | Intermediate file, providing an expanded list, or table of contents, of the entity fields' features, including fields from embedded entities. |
| DB/mold1-.coll | Intermediate file, providing a list of the DB collections defined by the entity, also checking for project-conformant collection names. |
| DB/mold2-.sql | SQL script to create a database table as defined by collections DB.table and DB.pkey. |
| LOGIC/mold1-.coll | Intermediate file, providing a list of the LOGIC collections defined by the entity, also checking for project-conformant collection names. |
| LOGIC/mold2-.java | Java[tm] class source file, defining a Java[tm] class derived from collections LOGIC.class and LOGIC.parent. |
| LOGIC/mold3-.h | C++ header file, defining a C++ class derived from collections LOGIC.class and LOGIC.parent. |
| LOGIC/mold4-.cpp | C++ file to check compilability of generated C++ header file. |
| UI/mold1-.coll | Intermediate file, providing a list of the UI collections defined by the entity, also checking for project-conformant collection names. |
| UI/mold2-.fview | Intermediate file, providing an HTML user interface as defined by collection UI.full_view, contained in a ready-to-use HTML table to be embedded in an HTML form. |
| UI/mold3-.cview | Intermediate file, providing an HTML table as defined by collection UI.compact_view. This table represents a Sisendel list at the UI layer level, and is to be embedded in the HTML user interface form of those entities that include a list of this entity in their UI.full_view. |
| UI/mold4-.html | HTML edit/view form as defined by collection UI.full_view. |
| DOC/mold1-.html | HTML documentation file about the entity, its collections and its functions. |
The mold kit includes the following project customization scripts:
| Script name | Description |
|---|---|
| apply_filter | Apply a Tefigel FILTER to a given intermediate generated file |
| check_collection | Verify a collection name against the project conventions |
| cpp/get | Generate a C++ "get" method |
| cpp/link | Handle C++ mapping of Sisendel simple relationship |
| cpp/param | Handle parameter generation for C++ methods |
| cpp/set | Generate a C++ "set" method |
| cpp/type | Handle C++ mapping of most Sisendel types |
| embed_subent | Handle generation of embedded collection members from an embedded entity |
| ent_warning | Project-customizable warning message routine |
| ets_process | Handle generic generation of embedded entities |
| html/formbuttons | Generate a row of buttons for an HTML form |
| html/formbutton | Generate one HTML form button |
| html/membership | Generate documentation about the collection memberships of an entity field |
| html/tablehdr | Generate a standard table header for documentation purposes |
| indent | Code-indenting script |
| iseven | Boolean function: returns true if argument is an even number |
| java/get | Generate a Java[tm] "get" method |
| java/link | Handle Java[tm] mapping of Sisendel simple relationship |
| java/param | Handle parameter generation for Java[tm] methods |
| java/set | Generate a Java[tm] "set" method |
| java/type | Handle Java[tm] mapping of most Sisendel types |
| link_subent | Handle generation of embedded collection members from a related entity |
| list/add | Add an item to a list |
| list/contains | Boolean function: returns true if a given list contains a given item |
| list/contents | Function: returns contents of a list |
| list/create | Create a new list |
| list/delete | Delete an existing list |
| list/print | Print contents of a list |
| list/process | Apply a given list item processor to a given list |
| print_item | Print one item of a list |
| proj_package | Convert an entity file path within a SoProTech project into a valid Java[tm] or C++ package name |
| sql/column | Generate a column definition for an SQL database table |
| sql/pkey | Add a given field to a list of primary keys for an SQL database table |
Even if the sample project is a small, simple project, nonetheless
it allows to define a number of conventions that the molds should
implement and possibly verify, for instance to issue a warning
message in case
of inconsistency. Project conventions vary in type
and complexity, ranging from simple naming and layer design
conventions to more complex multilayer conventions.
In most cases the most simple conventions are usually implicitly
assumed by an expert project team, which is reasonable: the
intent of this paragraph
is simply to show that even such fine-grained conventions can be
actively implemented and documented in a set of molds.
The following table describes some naming conventions, indicating
in which mold, or part thereof, or toolkit script, they are implemented.
| Convention | Description | Example | Relevant mold or script |
|---|---|---|---|
| Database column names | Should be all in lower case letters with no underscores | emplid |
DB/ mold2-.sql/ 1/ any_type.hdr |
| Java[tm] class member names | Should be in mixed upper case and lower case letters with no underscores | EmplId |
LOGIC/ mold2-.java/ 4/ any_type.hdr |
| Java[tm] class source file names | Should match the Java[tm] class name, with the first letter in upper case | Customer |
LOGIC/ mold2-.java/ trigger |
A project convention that impacts the design style of a single
system layer level can be classified as a layer design convention:
for example, deciding that an entity should have exactly one primary
key at DB level does not force to use exactly the same
key in the UI design of a search function for the entity.
In most cases, layer design conventions are a matter of programming style
in a broad sense.
The following table describes some conventions of layer design, indicating
in which mold, or part thereof, or toolkit script, they are implemented.
| Convention | Description | Example | Relevant mold or script |
|---|---|---|---|
| DB collections | Each entity requiring SQL data persistence should define collections DB.table and DB.pkey; collection DB.null is optional |
table: company_name, address, contact |
DB/ mold1-.coll/ 1 |
| UI collections | Each entity requiring an HTML data editing/viewing form should define collections UI.full_view and UI.compact_view |
full_view: company_name address contact phone_call cell_call |
UI/ mold1-.coll/ 1 |
| Database table keys | Each database table should have exactly one primary key |
constraint pk_employee primary key (emplid) |
DB/ mold2-.sql/ 2 |
| HTML form buttons | Each full_view HTML form should have the same set of buttons at the bottom of its entity workspace |
New Copy Save Delete Search Prev. Next Navigate |
toolkit/ html/ formbuttons |
| C++ enumeration values | Should be identified by upper case symbolic names and their values should always be explicitly expressed |
VICE_PRESIDENT = 1 |
LOGIC/ mold3-.h/ 3/ enum |
Multilayer conventions are those project
conventions that affect more than one software
system layer. For example, the decision on how a simple relationship
between two entities is
implemented in the DB, LOGIC and UI layers
may have a major influence on the performance and
maintainability of the target software system.
Another example of
multilayer convention is what can be defined
as the middleware relay that transmits a request
from the UI to a legacy transaction - logically
belonging to the DB layer - via an intermediate
dispatcher at the LOGIC layer level.
This type of conventions usually involves overall software system
design decisions, that should ideally be agreed upon by the
project team at project start-up time. These conventions
are particularly important from the SoProTech perspective, because:
The following table describes some multilayer conventions of the
sample project, specifying
in which mold or script they are implemented.
| Convention | Description | Example | Relevant mold or script |
|---|---|---|---|
| SQL mapping of Sisendel enums | Sisendel enums should be mapped to SQL varchar, large enough to hold the Sisendel enum label |
position varchar(40) |
toolkit/ sql/ column |
| Java[tm] mapping of Sisendel enums | Sisendel enums should be mapped to Java[tm] int private members, whereas their values should be implemented as final int public members identified by upper case symbolic names |
public final int VICE_PRESIDENT = 1; ... private int position; |
LOGIC/ mold2-.java/ 3/ enum LOGIC/ |
| HTML mapping of Sisendel enums | Sisendel enums should be mapped to HTML select/option lists, and the labels of their values should appear as both value and label of the HTML option |
<option value= "Vice-president"> Vice-president </option> |
UI/ mold2-.fview/ 1/ enum |
It should be noted that the three mappings in the example above are tightly related with one another: when option Vice-president is selected by a user on the data-entry HTML form at UI level, the LOGIC-layer Java[tm] class member position gets set to VICE_PRESIDENT. Finally, when an SQL insert or update is executed, the DB column position is set to "Vice-president". In this particular case, it would probably make sense to change the Java[tm] mapping convention, thus avoiding the conversion from string (at UI level) to Java[tm] int and again to SQL varchar. But this type of decisions vary from project to project, therefore the SoProTech[tm] does not enforce any predefined type-mapping scheme.
This chapter describes the first simulation exercise of system
modification on the sample SoProTech project. The exercise
simulates a simplified change management process, consisting
of the following steps:
In this exercise an apparently small change is applied to one single
entity, showing how SoProTech[tm] can help software development teams
apply local changes that automatically have cascading effects on several
parts of the software system.
The sample project entity country has been initially designed as a single-field entity containing the country name, as shown in the following code example.
Entity country consists of just one enum (lines 4 and 7-14). Adjusting parameter DB.table.create on line 25 is set to "false", hence no database table is created for country. Collection DB.table (lines 16-17) defines the set of country fields to be embedded in the database table of other entities that embed country as one of their own DB.table members. |
| Source code - File "country.ef" |
1 country "Country"
2 | A national country
3
4 enum country "Country"
5
6 ----------------------- DEFS
7 country:
8 usa "USA"
9 canada "Canada"
10 japan "Japan"
11 france "France"
12 uk "UK"
13 espana "Espaņa"
14 india "India"
15 ----------------------- DB
16 table:
17 country
18 ----------------------- LOGIC
19 class:
20 country
21 ----------------------- UI
22 full_view:
23 country
24 ----------------------- ADJUST
25 DB.table.create = "false"
|
The project team is requested to adapt the software system, so that it handles national or federated currencies.
The project team decides to insert a new enum field currency
into entity country.
Entity country is logically located at
the bottom of the entity relationships graph:
it consists of a single, basic type field, and it is
embedded in entities person_info (as field nationality)
and address (as field country), which are in turn
embedded in higher-level entities.
Thus, as small as this change may appear, it actually impacts
several aspects of all layers of the system, for example:
Changes 1 and 2 in the previous list can be accomplished directly in "country.ef", as shown in the following code example.
The extended entity country contains a new enum currency (lines 5 and 17-25), which is added as a new member to collections DB.table, LOGIC.class and UI.full_view. |
| Source code - File "location/country.ef" |
1 country "Country"
2 | A national country
3
4 enum country_name "Country"
5 enum currency "Currency"
6
7 ----------------------- DEFS
8 country_name:
9 usa "USA"
10 canada "Canada"
11 japan "Japan"
12 france "France"
13 uk "UK"
14 espana "Espaņa"
15 india "India"
16
17 currency:
18 us_dollar "US dollar"
19 cnd_dollar "Canadian dollar"
20 yen "Yen"
21 french_franc "French franc"
22 uk_pound "UK pound"
23 peseta "Peseta"
24 rupia "Rupia"
25 euro "Euro"
26
27 ----------------------- DB
28 table:
29 country_name, currency
30
31 pkey:
32 country_name
33 ----------------------- LOGIC
34 class:
35 country_name, currency
36 ----------------------- UI
37 full_view:
38 country_name
39 currency
40 ----------------------- ADJUST
41 DB.table.create = "true"
|
Changes 3 and 4 are logically more subtle: the point is that an address and a set of person_info should not directly embed the data fields of a country. Instead, they should relate to one country.
Therefore, changes 3 and 4 merely require to add the Sisendel type specifier link in the definition of fields address.country and person_info.nationality, which are both of the Sisendel type country.
Such simple changes can be applied within minutes using a standard text editor. No changes on the molds are required: it is thus sufficient to run the Somusar/Software Production Machine[tm] in order to re-generate within a few seconds all software files (including DOCumentation pages) for all entities: on a 1700 MHz Intel®-based Linux® PC with 256 MB RAM the complete automatic production process required less than 7 seconds.
The comparison between the files generated before and after
modifying the entity files
show an impressive amount of comparatively small
consistent changes scattered across several generated files.
The table below lists the impacted files and describes these changes.
| Generated file | Description of change |
|---|---|
| business/DB/customer.sql | Column country renamed to countryname |
| company/DB/employee.sql | Column infonationalitycountry renamed to infonationalitycountryname |
| location/DB/country.sql | New SQL script to create table country |
|
location/LOGIC/Address.h persons/LOGIC/PersonInfo.h |
Member of type Country replaced by an int representing the relationship to class Country; related get/set methods accordingly changed |
| location/LOGIC/Country.h | Member country and related get/set methods changed to countryName; new type enumCurrency and new member currency, with related get/set methods |
|
location/LOGIC/Address.java persons/LOGIC/PersonInfo.java |
Member of type Country replaced by an int representing the relationship to class Country; related get/set methods accordingly changed |
| location/LOGIC/Country.java | Member country and related get/set methods changed to countryName; new mapping for Sisendel enum Currency and new int member currency, with related get/set methods |
|
business/UI/customer.fview company/UI/employee.fview location/UI/address.fview location/UI/country.fview persons/UI/person_info.fview |
Same changes as in corresponding UI/<entity>.html files below |
|
business/UI/customer.html company/UI/employee.html location/UI/address.html persons/UI/person_info.html |
Embedded country replaced by a reference to it |
| location/UI/country.html | select name="country" replaced by select name="country_name"; new select/option list for currency |
|
location/DOC/address.html location/DOC/country.html persons/DOC/person_info.html |
Updated entity documentation pages |
The following code examples and illustrations describe in more detail some of the changes listed above.
Code Example 3 - New SQL script "country.sql"
The new database table is required to keep track of national country currencies. |
| Source code - File "location/DB/country.sql" |
1 --
2 -- This SQL script created by somusar/SoProMach[tm]
3 --
4
5 create table country (
6 countryname varchar(40) not null,
7 currency varchar(40) not null,
8 constraint pk_country primary key (countryname)
9 )
10 ;
11
|
Code Example 4 - Changes in "Country.java" due to new country.currency field
The changes caused by adding field currency can be seen on lines 25-33, 36, 46-48, 58-60. |
| Source code - File "location/LOGIC/Country.java" |
1 /*
2 * This Java class generated by somusar/SoProMach[tm].
3 */
4
5 package com.somusar.entdemo.location;
6
7 /**
8 * Class Country:
9 *
10 * A national country.
11 */
12
13
14 public class Country {
15
16 // Map enum 'Country' onto an int with a set of values
17 public final int USA = 0; // USA
18 public final int CANADA = 1; // Canada
19 public final int JAPAN = 2; // Japan
20 public final int FRANCE = 3; // France
21 public final int UK = 4; // UK
22 public final int ESPANA = 5; // Espaņa
23 public final int INDIA = 6; // India
24
25 // Map enum 'Currency' onto an int with a set of values
26 public final int US_DOLLAR = 0; // US dollar
27 public final int CND_DOLLAR = 1; // Canadian dollar
28 public final int YEN = 2; // Yen
29 public final int FRENCH_FRANC = 3; // French franc
30 public final int UK_POUND = 4; // UK pound
31 public final int PESETA = 5; // Peseta
32 public final int RUPIA = 6; // Rupia
33 public final int EURO = 7; // Euro
34
35 private int countryName; // enum 'Country'
36 private int currency; // enum 'Currency'
37
38 /*
39 * Get methods
40 */
41
42 public int getCountryName() {
43 return countryName;
44 }
45
46 public int getCurrency() {
47 return currency;
48 }
49
50 /*
51 * Set methods
52 */
53
54 public void setCountryName( int countryName ) {
55 this.countryName = countryName;
56 }
57
58 public void setCurrency( int currency ) {
59 this.currency = currency;
60 }
61
62 }
|
Code Example 5 - Changes in "PersonInfo.h" due to new country.currency field
Entity person_info, that formerly embedded country, has now a link to it. The related changes can be seen on lines 37, 54-57, 74-77. |
| Source code - File "persons/LOGIC/PersonInfo.h" |
1 #ifndef __PersonInfo__
2 #define __PersonInfo__
3
4 /*
5 * -----------------------------------------------------------------
6 * Class PersonInfo
7 *
8 * Private information, to be kept distinct from employee
9 * info.
10 * -----------------------------------------------------------------
11 *
12 * [This header generated by somusar/SoProMach[tm].]
13 */
14
15
16
17 #ifndef __dummy_classes__
18 # define __dummy_classes__
19
20 /* Dummy declarations, just for compiling. */
21 class Collection { char s[100]; };
22 class Object { char s[100]; };
23
24 #endif
25
26 #include <String.h>
27
28 #include "location/Country.h"
29 #include "Image.h"
30
31 class PersonInfo {
32
33 private:
34
35 int age; // 18-120; would fit in a uint8
36 String ssn;
37 int nationalityCountryName; // relationship to Country
38 Image photo;
39
40 public:
41
42 /*
43 * Get methods
44 */
45
46 int getAge() {
47 return age;
48 }
49
50 String getSsn() {
51 return ssn;
52 }
53
54 int getNationalityCountryName() {
55 return nationalityCountryName;
56 }
57
58 Image getPhoto() {
59 return photo;
60 }
61
62 /*
63 * Set methods
64 */
65
66 void setAge( int age ) {
67 this->age = age;
68 }
69
70 void setSsn( String ssn ) {
71 this->ssn = ssn;
72 }
73
74 void setNationalityCountryName( int nationalityCountryName ) {
75 this->nationalityCountryName = nationalityCountryName;
76 }
77
78 void setPhoto( Image photo ) {
79 this->photo = photo;
80 }
81
82 };
83
84 #endif /* __PersonInfo__ */
|
The next illustrations show the user interface form for entity customer before and after adding field country.currency.
Figure 2 - "UI/customer.html" without country.currency
Figure 3 - Changes in "UI/customer.html" due to country.currency
The following illustrations show the documentation page for entity country before and after adding field currency.
Figure 4 - "DOC/country.html" without currency
Figure 5 - Changes in "DOC/country.html" due to currency
In the second exercise a new entity is added to the sample software system, showing how SoProTech[tm] can support incremental growth of medium and large software systems over time.
The careful reader may have noticed that a key entity
is missing in the sample project: no entity company has
been defined. In fact, after an early design review,
the sample project team decides to add entity company,
which logically belongs to project directory "project/company",
as shown in the reviewed entity-relationships diagram.
Figure 6 - Modified entity/relationships diagram
The DB expert of the team suggests that an SQL
company table is definitely necessary, and that it
should contain the following columns:
Beyond those fields, the object-oriented expert suggests
that the Java[tm] and C++ classes would benefit of
lists of the company's employees, customers,
and projects.
A first version of "company/company.ef" is
quickly ready, and a few tries at generating the HTML full_view form
convince the UI expert to suggest a change in the project
conventions, as the full_view of the company
has too many lists, that make it too big to fit on the screen.
Therefore a new adjusting parameter for the UI facet is added
to the project conventions, and two scripts of mold
"UI/mold2-.fview" are accordingly extended.
The final version of "entity.ef" is thus ready,
and - due to the new project convention - a complete
re-generation of all software files, and a comparison
with the previous version of generated files are deemed
advisable. So the SoProMach[tm] is started.
After seven seconds all newly generated files - a little
more than one hundred files - can be compared with their
former counterparts, and
the comparison ensures that no undesired changes
have taken place. Depending on their system layer expertise,
the project team members check that the files
generated for the new entity company are correct,
and integrate them within the rest of the project.
The next code example describes the new entity. The most
relevant generated files are listed, or shown, in
the following code examples and illustrations.
The new entity is similar to the other ones, except for several adjusting parameters for its UI.full_view (lines 32-37). In particular, a new adjusting parameter make_button is used on lines 35-37 for three lists within the full_view. |
| Source code - File "company/company.ef" |
1 company "Company"
2 | A commercial company, its address, personnel, customers and activities
3
4 strings.name company_name "Company name"
5 strings.description business "Business description"
6 address headquarters "Headquarters address"
7 list employee employees "Employees"
8 list department departments "Departments"
9 list customer customers "Customers"
10 list project projects "Projects"
11
12 ------------------------- DEFS
13 ------------------------- DB
14 table:
15 company_name, departments, headquarters, business
16
17 pkey:
18 company_name
19 ------------------------- LOGIC
20 class:
21 company_name, business, headquarters, employees, departments, customers, projects
22 ------------------------- UI
23 full_view:
24 company_name...........
25 business.customers.....
26 .........employees.....
27 .........projects......
28 .........departments...
29 headquarters...........
30 ------------------------- ADJUST
31 DB.table.create = "true"
32 UI.full_view.company_name.colspan = "3"
33 UI.full_view.business.rowspan = "4"
34 UI.full_view.headquarters.colspan = "3"
35 UI.full_view.employees.make_button = "true"
36 UI.full_view.departments.make_button = "true"
37 UI.full_view.projects.make_button = "true"
|
Figure 7 - From UI.full_view to "company.html"
Code Example 7 - From DB.table and DB.pkey to "company.sql"
The SQL script to create the company table fully complies with the project conventions. |
| Source code - File "company/DB/company.sql" |
1 --
2 -- This SQL script created by somusar/SoProMach[tm]
3 --
4
5 create table company (
6 companyname varchar(40) not null,
7 departmentsdeptid varchar(10) not null,
8 headquartersstreet varchar(80) not null,
9 headquarterscity varchar(80) not null,
10 headquartersstate varchar(40) null,
11 headquarterszip varchar(20) not null,
12 headquarterscountryname varchar(40) not null,
13 headquarterswebsite varchar(80) null,
14 business varchar(200) not null,
15 constraint pk_company primary key (companyname)
16 )
17 ;
18
|
Code Example 8 - From LOGIC.class to "Company.java"
This Java class source file fully complies with the project conventions. |
| Source code - File "company/LOGIC/Company.java" |
1 /*
2 * This Java class generated by somusar/SoProMach[tm].
3 */
4
5 package com.somusar.entdemo.company;
6
7 /**
8 * Class Company:
9 *
10 * A commercial company, its address, personnel,
11 * customers and activities.
12 */
13
14 import com.somusar.entdemo.location.Address;
15 import com.somusar.entdemo.company.Employee;
16 import java.util.Collection;
17 import com.somusar.entdemo.company.Department;
18 import com.somusar.entdemo.business.Customer;
19 import com.somusar.entdemo.business.Project;
20
21 public class Company {
22
23 private String companyName;
24 private String business;
25 private Address headquarters;
26 private Collection employees;
27 private Collection departments;
28 private Collection customers;
29 private Collection projects;
30
31 /*
32 * Get methods
33 */
34
35 public String getCompanyName() {
36 return companyName;
37 }
38
39 public String getBusiness() {
40 return business;
41 }
42
43 public Address getHeadquarters() {
44 return headquarters;
45 }
46
47 public Collection getEmployees() {
48 return employees;
49 }
50
51 public Collection getDepartments() {
52 return departments;
53 }
54
55 public Collection getCustomers() {
56 return customers;
57 }
58
59 public Collection getProjects() {
60 return projects;
61 }
62
63 /*
64 * Set methods
65 */
66
67 public void setCompanyName( String companyName ) {
68 this.companyName = companyName;
69 }
70
71 public void setBusiness( String business ) {
72 this.business = business;
73 }
74
75 public void setHeadquarters( Address headquarters ) {
76 this.headquarters = headquarters;
77 }
78
79 public void setEmployees( Collection employees ) {
80 this.employees = employees;
81 }
82
83 public void setDepartments( Collection departments ) {
84 this.departments = departments;
85 }
86
87 public void setCustomers( Collection customers ) {
88 this.customers = customers;
89 }
90
91 public void setProjects( Collection projects ) {
92 this.projects = projects;
93 }
94
95 }
|
Figure 8 - Documentation generated for company
In the third exercise a set of cross-layer changes is applied that impacts several entities, if not all, of the sample project. This simulation aims at showing how the Somusar/Software Molds[tm] can support software developers in managing the evolution of requirements and conventions, that can possibly impact a large part of a software system.
A set of new requirements is submitted to the project team by
the customer's project manager who is responsible for the application.
The new requirements impact:
In particular, all not null clauses should be
deleted from the SQL scripts, whereas all members of all collections
DB.null should preserve the correspondent null clause.
The details of the new requirements for the user interface are as follows:
The project team evaluates the request for change and the analysis shows that no entity is impacted by the request for change: only local changes to two molds are required, then all files can be re-generated using the SoProMach[tm].
The DB expert of the team quickly realizes that the new SQL
requirement can be met by changing just three lines in one mold
script, namely toolkit/sql/column.
The web page designer, using his or her favorite tool, updates the
generic HTML reference page, which is then approved by the customer's
project manager. The HTML source of the new reference page is then compared
with the previous one, and the required textual changes are integrated
in script "file.hdr" of mold "UI/mold4-.html". A set
of generation flags - such as COLORSCHEME and ADVERTISINGVERTBAR -
are locally added to the script, to increase its flexibility
and ensure that it be backward compatible. Comments are locally added, to
document the changes in the molds, then the SoProMach[tm] is started.
Once again, in about seven seconds all files are re-generated.
A comparison with the previous version confirms that no undesired
changes have crept into the generated files, that
can now be integrated in the project source tree.
All SQL files of layer DB, as well as all HTML files of layer UI are impacted by the change. As an example, the new versions of "DB/company.sql" and "UI/employee.html" are shown below.
In the new "company.sql" SQL clause "not null" have disappeared from lines 6-9, 11-12 and 14. |
| Source code - File "company.sql" |
1 --
2 -- This SQL script created by somusar/SoProMach[tm]
3 --
4
5 create table company (
6 companyname varchar(40),
7 departmentsdeptid varchar(10),
8 headquartersstreet varchar(80),
9 headquarterscity varchar(80),
10 headquartersstate varchar(40) null,
11 headquarterszip varchar(20),
12 headquarterscountryname varchar(40),
13 headquarterswebsite varchar(80) null,
14 business varchar(200),
15 constraint pk_company primary key (companyname)
16 )
17 ;
18
|
Figure 9 - New version of "UI/employee.html"
As a comparison term, the former version of "UI/employee.html" is shown in the following figure.
Figure 10 - Former version of "UI/employee.html"
Additional information on the different aspects of the
Somusar/Software Production Technique[tm] can be found in the other volumes of
the Somusar/SoProTech[tm] Booklet Series, listed below.
Vol. I -
somusar/SoProTech: An Introduction
Vol. III -
somusar/Sisendel: A Tutorial Introduction
Vol. IV -
somusar/Tefigel: A Tutorial Introduction
Vol. V -
somusar/Sisendel: Reference Guide
Vol. VI -
somusar/Tefigel: Reference Guide
Vol. VII -
somusar/SoProMach: User's Guide
Vol. VIII -
somusar/tjpp: User's Guide
Vol. IX -
Code Generation Somusar Style
An introduction to the Somusar/Software Production Technique[tm], a new, fast, and efficient
technology to make high-quality multifacet software.
A tutorial introduction to Somusar/Sisendel[tm], describing all
features of the simple software entity design language. Several code examples
practically demonstrate the conciseness and flexibility
of the language.
An introduction to the syntax, semantics, and usage of Somusar/Tefigel[tm],
including a vast set of code examples, illustrating the powerful
features of the text file generation language.
Sisendel reference guide: official definition of syntax and semantics
of the Somusar/Sisendel[tm] language.
Tefigel reference guide: official definition of syntax and semantics
of the Somusar/Tefigel[tm] language.
The Somusar/Software Production Machine[tm] User's Guide. How to install and operate
SoProMach.
The Somusar/tjpp[tm] User's Guide. How to install and operate
the Java[tm] preprocessor.
Proof-of-concept samples of what you can generate with Somusar/SoProMach[tm].
This appendix contains the final version of all project entities from the sample project.
| Entity business/customer - File "sample_project/project/business/customer.ef" |
|---|
1 customer "Customer"
2 | A company/organization, its address, and a contact person
3
4 strings.long_string company_name "Company name"
5 address address "Address"
6 person contact "Contact person"
7 function call_customer "Call customer"
8 enum call_mode "Call modality"
9 function phone_call "Call cust. by phone"
10 function cell_call "Call cust. by cell."
11
12 ----------------------- DEFS
13 call_mode:
14 by_phone "By phone"
15 by_cell "By cell"
16
17 call_customer:
18 call_mode -> 0
19
20 phone_call:
21 0 -> 0
22
23 cell_call:
24 0 -> 0
25 ----------------------- DB
26 table:
27 company_name, address, contact
28 pkey:
29 company_name
30 ----------------------- LOGIC
31 class:
32 company_name, address, contact, call_customer, phone_call, cell_call
33 ----------------------- UI
34 full_view:
35 company_name
36 address
37 contact
38 phone_call
39 cell_call
40
41 compact_view:
42 company_name, contact
43 ----------------------- ADJUST
44 DB.table.create = "true"
45 LOGIC.class.phone_call.code = "callCustomer(BY_PHONE);"
46 LOGIC.class.cell_call.code = "callCustomer(BY_CELL);"
|
| Entity business/project - File "sample_project/project/business/project.ef" |
|---|
1 project "Project"
2 | A project within a company, some information about it, a project
3 | manager, the involved personnel, a project plan and budget
4
5 strings.name proj_name "Project name"
6 strings.id proj_id "Project id."
7 strings.description descr "Description"
8 link customer customer "Customer"
9 float budget "Budget (K$)"
10 list employee team_members "Team members"
11 link employee manager "Proj. manager"
12 link department department "Department"
13 bool internal "Internal"
14 thing plan "Proj. plan"
15 function cur_status "Current proj. status"
16 enum status "Proj. status"
17
18 ----------------------- DEFS
19 budget:
20 0/1000
21 status:
22 ok "OK"
23 late "Late"
24 danger "Danger"
25 cur_status:
26 plan, budget -> status
27 ----------------------- DB
28 table:
29 proj_id, proj_name, descr, customer, budget, team_members,
30 manager, department, internal
31 pkey:
32 proj_id
33 ----------------------- LOGIC
34 class:
35 proj_id, proj_name, descr, customer, budget, team_members,
36 manager, department, internal, cur_status
37 ----------------------- UI
38 full_view:
39 proj_name proj_id
40 customer descr
41 budget cur_status
42 manager team_members
43 department internal
44
45 compact_view:
46 proj_name, customer, budget
47 ----------------------- ADJUST
48 DB.table.create = "true"
|
| Entity company/company - File "sample_project/project/company/company.ef" |
|---|
1 company "Company"
2 | A commercial company, its address, personnel, customers and activities
3
4 strings.name company_name "Company name"
5 strings.description business "Business description"
6 address headquarters "Headquarters address"
7 list employee employees "Employees"
8 list department departments "Departments"
9 list customer customers "Customers"
10 list project projects "Projects"
11
12 ------------------------- DEFS
13 ------------------------- DB
14 table:
15 company_name, departments, headquarters, business
16
17 pkey:
18 company_name
19 ------------------------- LOGIC
20 class:
21 company_name, business, headquarters, employees, departments, customers, projects
22 ------------------------- UI
23 full_view:
24 company_name...........
25 business.customers.....
26 .........employees.....
27 .........projects......
28 .........departments...
29 headquarters...........
30 ------------------------- ADJUST
31 DB.table.create = "true"
32 UI.full_view.company_name.colspan = "3"
33 UI.full_view.business.rowspan = "4"
34 UI.full_view.headquarters.colspan = "3"
35 UI.full_view.employees.make_button = "true"
36 UI.full_view.departments.make_button = "true"
37 UI.full_view.projects.make_button = "true"
|
| Entity company/department - File "sample_project/project/company/department.ef" |
|---|
1 department "Department"
2 | A department within a company
3
4 strings.name dept_name "Dept. name"
5 strings.id dept_id "Dept. id."
6 link employee manager "Manager"
7 list employee members "Dept. members"
8 list project projects "Dept. projects"
9 function curr_projects "Current projects"
10
11 ----------------------- DEFS
12 curr_projects:
13 dept_id -> projects
14 ----------------------- DB
15 table:
16 dept_id, dept_name, manager, members
17 pkey:
18 dept_id
19 ----------------------- LOGIC
20 class:
21 dept_name, dept_id, manager, members, curr_projects
22 ----------------------- UI
23 full_view:
24 dept_name
25 dept_id
26 manager
27 members
28 curr_projects
29
30 compact_view:
31 dept_name, manager
32 ----------------------- ADJUST
33 DB.table.create = "true"
|
| Entity company/employee - File "sample_project/project/company/employee.ef" |
|---|
1 employee "Employee"
2 | An employee, some related information, and the department s/he works in
3
4 person person "Person"
5 person_info info "Pers. info"
6 link department dept "Department"
7 enum position "Position"
8 float salary "Salary ($)"
9 unique_id empl_id "Employee id."
10
11 ----------------------- DEFS
12 salary:
13 0/1000000
14 position:
15 president "President"
16 vice_president "Vice-president"
17 manager "Manager"
18 admin "Admin"
19 sales_rep "Sales rep."
20 engineer "Engineer"
21 ----------------------- DB
22 table:
23 empl_id, person, info, dept, position, salary
24 pkey:
25 empl_id
26 ----------------------- LOGIC
27 class:
28 empl_id, info, dept, position, salary
29 parent:
30 person
31 ----------------------- UI
32 full_view:
33 empl_id
34 person
35 dept
36 position
37 salary
38 info
39
40 compact_view:
41 empl_id, person, position
42 ----------------------- ADJUST
43 DB.table.create = "true"
|
| Entity location/address - File "sample_project/project/locatio |
|---|