|
|
|
|
Somusar/Software Production Technique[tm]
A Sample Project Francesco Aliverti-Piuri Copyright © 2003-2012 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/location/address.ef" |
---|
1 address "Address" 2 | Address of an organization 3 4 strings.long_string street "Street" 5 strings.long_string city "City" 6 enum state "State or Province" 7 strings.short_string zip "Postal Code" 8 link country country "Country" 9 strings.long_string web_site "Web site" 10 11 ----------------------- DEFS 12 state: 13 not_applicable "Not applicable" 14 california "California" 15 new_york "New York" 16 texas "Texas" 17 ontario "Ontario" 18 quebec "Quebec" 19 yorkshire "Yorkshire" 20 kent "Kent" 21 asturias "Asturias" 22 galicia "Galicia" 23 ----------------------- DB 24 table: 25 street, city, state, zip, country, web_site 26 null: 27 state, web_site 28 ----------------------- LOGIC 29 class: 30 street, city, state, zip, country, web_site 31 ----------------------- UI 32 full_view: 33 street city 34 state zip 35 country web_site 36 ----------------------- ADJUST 37 DB.table.create = "false" 38 UI.full_view.web_site.init = "http://www." |
Entity location/country - File "sample_project/project/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" |
Entity persons/person - File "sample_project/project/persons/person.ef" |
---|
1 person "Person" 2 | Commercial information about a person, basically name and 3 | how to reach him/her 4 5 strings.name first_name "First name" 6 strings.name last_name "Last name" 7 strings.email email_addr "Email address" 8 strings.telephone telephone "Telephone" 9 strings.telephone cell_phone "Mobile" 10 11 ----------------------- DEFS 12 ----------------------- DB 13 table: 14 last_name, first_name, email_addr, telephone, cell_phone 15 pkey: 16 last_name 17 null: 18 telephone, cell_phone 19 ----------------------- LOGIC 20 class: 21 first_name, last_name, email_addr, telephone, cell_phone 22 ----------------------- UI 23 full_view: 24 first_name last_name 25 email_addr 26 telephone cell_phone 27 28 compact_view: 29 last_name, telephone 30 ----------------------- ADJUST 31 DB.table.create = "false" 32 UI.full_view.email_addr.colspan = "2" |
Entity persons/person_info - File "sample_project/project/persons/person_info.ef" |
---|
1 person_info "Personal information" 2 | Private information, to be kept distinct from employee info 3 4 range age "Age" 5 strings.ssn ssn "Social security #" 6 link country nationality "Nationality" 7 image photo "Photo" 8 9 ----------------------- DEFS 10 age: 11 18/120 12 ----------------------- DB 13 table: 14 age, ssn, nationality, photo 15 ----------------------- LOGIC 16 class: 17 age, ssn, nationality, photo 18 ----------------------- UI 19 full_view: 20 age photo 21 ssn 22 nationality 23 24 compact_view: 25 age 26 ----------------------- ADJUST 27 DB.table.create = "false" 28 UI.full_view.photo.size = "70x100" 29 UI.full_view.photo.rowspan = "3" |
This appendix contains the final version of all library entities from the sample project.
Entity image - File "sample_project/library/image.ef" |
---|
1 image "Project-wide image definition" 2 | A photo, an illustration, or a picture 3 4 strings.pathname img_file "Image file" 5 6 ----------------------- DEFS 7 ----------------------- DB 8 table: 9 img_file 10 ----------------------- LOGIC 11 class: 12 img_file 13 ----------------------- UI 14 | UI representation of the image is handled directly 15 | in the UI molds 16 ----------------------- ADJUST 17 DB.table.create = "false" |
Entity strings - File "sample_project/library/strings.ef" |
---|
1 strings "Project-wide strings definitions" 2 | Various types of strings, standardized across the project 3 4 string long_string[80] "Long string" 5 string mid_string[40] "Mid string" 6 string short_string[20] "Short string" 7 string very_long_string[255] "Very long string" 8 string password[40] "Password" 9 string status[2] "Status" 10 string id[10] "Identifier" 11 string user_id[80] "User id." 12 string name[40] "Name" 13 string telephone[40] "Tel. number" 14 string email[60] "Email address" 15 string description[200] "Short description" 16 string ssn[40] "Social security number" 17 string pathname[1024] "Pathname" 18 19 DEFS 20 DB 21 LOGIC 22 UI 23 ADJUST |