|
|
|
|
|
|
Somusar/Sisendel[tm]
A Tutorial Introduction Francesco Aliverti-Piuri Copyright © 2003-2007 Somusar |
|
|
|
|
|
|
|
|
|
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 is a compact introduction to the syntax,
semantics and usage of Somusar/Sisendel[tm], which can be defined
at the same time as a special-purpose computer language and
the translator program for the language. More specifically,
Somusar/Sisendel[tm] is the front-end language of the Somusar/Software Production Machine[tm].
Purpose of this document is to concisely explain how to use
Somusar/Sisendel[tm] - hereinafter referred to as Sisendel - to increase productivity
and consistency within software development projects; in particular,
Sisendel can be extremely useful within large projects aimed
at implementing complex software systems which are planned to be
in production and maintained possibly for years; but even
individual developers working on several small-scale projects
will find Sisendel an unprecedented tool to boost their overall productivity.
The Sisendel language is a special-purpose
computer language, as opposed to
general-purpose programming languages such as Java[tm], C#, C++, or
COBOL. This means that
it is not possible to directly write a stand-alone, runnable
computer program in Sisendel, although Sisendel can be
used to generate such programs.
As a computer language, Sisendel is twofold:
The Somusar/Sisendel[tm] language processor is
currently available for the
following platforms:
Additional details
and the exact definition of the syntax and semantics of
Sisendel are provided in
"Somusar/Sisendel[tm]: Reference Guide
".
A remarkable feature of Sisendel is its language-neutrality:
Software Entities written in Sisendel can be used to generate software
in practically any computer language, both general-purpose
and special-purpose, ranging from
procedural languages like COBOL, C, or Fortran,
to object-oriented languages like Java[tm], C# and C++, and to
a great variety of specialized languages, like SQL, HTML, or XML.
The examples of generated code contained in this document, for instance,
are written in HTML, SQL, Java[tm], and C++, but they might as well
have been produced using virtually any other human-readable computer
language.
The Somusar/Software Entities[tm] are plain text files containing a formal,
yet simple, definition of the several facets that a
software entity (in a broad sense) may have with respect
to the several layers, or tiers, that a complex software system
may consist of.
As an example, the software representation of a customer
may include the following facets:
Sisendel allows to gather all facets of a software entity
and describe them in a simple fashion within one text file
that lists all data fields and data processing functions
related to that entity. Moreover, the contents of the entity file
drive the high-speed, multifacet software generation
performed by the Sisendel language processor within the context
of the Somusar/Software Production Technique[tm].
The foundation of a Software Entity consists of the list
of its fields - its data items and data processing functions.
Upon this foundation, the facets of an entity are described in terms
of one or more collections (subsets) of fields, one facet for each
software layer or tier: for each facet an appropriate section
is provided within the entity file.
Entity fields in Sisendel are very flexible and comparatively
simple to define,
as they should as easily as possible be mapped to the large variety
of computer languages, and related types, that Sisendel can generate.
Simplicity is achieved by means of a fairly small set of predefined or
basic field types; flexibility is obtained by leaving
the mapping between Sisendel types and other languages'
types outside the Sisendel
language, and by implementing that mapping in the molds.
New Sisendel types, or user types can be defined
by simply creating entity files: for example, to
define the new Sisendel types project and department
a developer simply needs to create - anywhere in the project
or library directory tree - two new entity files "project.ef" and
"department.ef".
The three facets listed above may be, and usually are, implemented
using different computer languages: SQL, Java[tm] and HTML may for
instance be used for those facets. In most real cases,
each facet may offer a different
view of the customer data: the SQL, Java[tm] and HTML subsets of
customer data and data processing functions may logically not
completely overlap; for example, the HTML user interface
may display a string of characters containing the
result of a floating point operation performed by a method of the
Java[tm] class on the basis of two SQL database columns.
An overview of the main features of entity files is given by the following sample Somusar/Software Entity[tm].
This Somusar/Software Entity[tm] shows all basic features of Somusar/Sisendel[tm], namely: |
|
|
|
|
|
|
|
|
|
| Source code - File "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"
|
The Sisendel language defines a set of basic
types, most of which are similar, or even identical, to the basic
types of several computer languages, like C and its derivatives, or
Java[tm]: types like bool, or float, or the different integer
types are common to the most part, if not all, of those languages.
Some additional basic types of Sisendel derive from types available
in database-specific languages, such as SQL: for example,
time and unique_id, or similar types, are often
used in database tables.
The following table describes all Sisendel basic types. As noted
in the table, some field types require additional detailed information
in an appropriate section (called DEFS) of the relevant entity file.
| Type id | Description | Notes |
|---|---|---|
| bool | Boolean value | - |
| enum | Enumerated value | Enumeration values must be defined in section DEFS |
| float | Floating point number | Lower and upper bound of validity range may optionally be defined in section DEFS |
| function | Computational object | Function parameters and return value(s) must be defined in section DEFS |
| int8 | Signed 8-bit integer number | - |
| int16 | Signed 16-bit integer number | - |
| int32 | Signed 32-bit integer number | - |
| int64 | Signed 64-bit integer number | - |
| range | Range of integer values | Lower and upper bound of range must be defined in section DEFS |
| string | String of characters | Length of string must be specified, may be dynamic |
| thing | Generic object | Can be used as a placeholder for complex or multimedia objects, such as documents, sound files, and videoclips (or smell, taste and tactile files in the future). |
| time | Time value | - |
| uint8 | Unsigned 8-bit integer number | - |
| uint16 | Unsigned 16-bit integer number | - |
| uint32 | Unsigned 32-bit integer number | - |
| uint64 | Unsigned 64-bit integer number | - |
| unique_id | Unique identifier | - |
Arrays of basic types are defined by specifying their size - possibly dynamic - in square brackets after the field identifier.
Basic types can also be imported from other entities: this feature of Sisendel allows to centralize and share the definition of commonly used simple types, such as identifiers, descriptors and numeric quantities.
The following code example shows several definitions of basic type fields.
Code Example 2 - Use of basic types
File "theater_seat.ef" contains a software representation of a theater seat, defining several fields, but with no collection in sections DB, LOGIC and UI, to keep the example simple. Some notes: |
|
|
|
|
|
|
| Source code - File "theater_seat.ef" |
1 theater_seat "Theater seat"
2 | Entity representing a theater seat,
3 | actually an example of usage of built-in types
4
5 unique_id number "Seat number"
6 bool available "Available"
7 enum type "Seat type"
8 function cur_type "Curr. seat type"
9 float price "Price range"
10 | Price range expressed in USD
11 function cur_price "Curr. price"
12 string purchaser[dyn] "Purchaser"
13 strings.description customization "Customization"
14
15 ----------------------- DEFS
16 type:
17 stalls 'S' "Stalls"
18 pit 'P' "Pit"
19 box 'B' "Box"
20 gallery 'G' "Gallery"
21
22 cur_type:
23 number -> type
24
25 price:
26 0/7000
27
28 cur_price:
29 type, purchaser -> price
30 ----------------------- DB
31 ----------------------- LOGIC
32 ----------------------- UI
33 ----------------------- ADJUST
|
Each entity file in a SoProTech project or library implicitly defines a new Sisendel user type whose identifier is the base name of the file, without path and without suffix ".ef". Thus, "library/image.ef", which is listed below, defines the new Sisendel type image that can be consistently used by any SoProTech project that has access to that "library" directory.
The entity image is simply implemented as a pathname of an image file. It should be noted that: |
|
|
|
| Source code - File "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"
|
The new type and entity image is used by (actually, embedded in) entity "persons/person_info.ef", which is listed below.
Field photo is defined on line 7 as an embedded image, and then used in collections DB.table (line 14), LOGIC.class (line 17), and UI.full_view (line 20). Lines 27-28 adjust some parameters (size in pixels and row span) to ensure that the photo is properly displayed in the full_view. |
| Source code - File "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"
|
Embedding entities may have a different meaning and a different mold implementation, depending on the software layer where it is applied, and depending on the language used for producing the generatable files: for example, embedding entity B in the database table of entity A rather naturally maps to embedding the data columns of B among the data columns of A, taking care of the possible column names clash that may arise.
The next illustration shows the result of embedding entity image in the UI.full_view of entity person_info as field photo: besides, it should be noted that the size in pixels and row span of the embedded image are adjusted as specified in section ADJUST.
Figure 1 - image.UI.full_view embedded in person_info.UI.full_view
Defining simple entities and embedding them in higher-level entities is one of the main ways in Sisendel to cope with the complexity of software systems. Entity customer below shows an example of multilevel embedding, as it embeds person and address, which in turn embeds country.
Code Example 5 - Multilevel entity embedding
This entity embeds on line 5 an address, which is then used in collections DB.table (lines 26-27), LOGIC.class (lines 31-32) and UI.full_view (line 34). Zeroes (0) in function definitions (lines 18, 21 and 24) mean "void": functions phone_call and cell_call are in fact subroutines, or utility methods, without parameters. Lines 45 and 46 contain the LOGIC implementation of functions phone_call and cell_call. |
| Source code - File "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);"
|
The different results of this multilevel embedding example are shown in the following files and illustration:
Code Example 6 - SQL result of multilevel embedding
The database table customer embeds the (virtual) table address, as shown on lines 6-11. In particular, line 11 is the (virtual) database table of entity country, which is embedded by address. |
| Source code - File "business/DB/customer.sql" |
1 --
2 -- This SQL script created by somusar/SoProMach[tm]
3 --
4
5 create table customer (
6 companyname varchar(80) not null,
7 street varchar(80) not null,
8 city varchar(80) not null,
9 state varchar(40) null,
10 zip varchar(20) not null,
11 country varchar(40) not null,
12 website varchar(80) null,
13 contactlastname varchar(40) not null,
14 contactfirstname varchar(40) not null,
15 contactemailaddr varchar(60) not null,
16 contacttelephone varchar(40) null,
17 contactcellphone varchar(40) null,
18 constraint pk_customer primary key (companyname)
19 )
20 ;
21
|
Code Example 7 - Java[tm] result of multilevel embedding
The Java class Customer embeds on line 24 class Address, whose definition is imported on line 14. Lines 76 and 85 directly derive from section ADJUST (lines 39 and 40) of the entity file. |
| Source code - File "business/LOGIC/Customer.java" |
1 /*
2 * This Java class generated by somusar/SoProMach[tm].
3 */
4
5 package com.somusar.entdemo.business;
6
7 /**
8 * Class Customer:
9 *
10 * A company/organization, its address, and a contact
11 * person.
12 */
13
14 import com.somusar.entdemo.location.Address;
15 import com.somusar.entdemo.persons.Person;
16
17 public class Customer {
18
19 // Map enum 'Call modality' onto an int with a set of values
20 public final int BY_PHONE = 0; // By phone
21 public final int BY_CELL = 1; // By cell
22
23 private String companyName;
24 private Address address;
25 private Person contact;
26
27 /*
28 * Get methods
29 */
30
31 public String getCompanyName() {
32 return companyName;
33 }
34
35 public Address getAddress() {
36 return address;
37 }
38
39 public Person getContact() {
40 return contact;
41 }
42
43 /*
44 * Set methods
45 */
46
47 public void setCompanyName( String companyName ) {
48 this.companyName = companyName;
49 }
50
51 public void setAddress( Address address ) {
52 this.address = address;
53 }
54
55 public void setContact( Person contact ) {
56 this.contact = contact;
57 }
58
59 /**
60 * Method 'Call customer'
61 */
62
63 public void callCustomer (
64 int callMode
65 )
66 {
67 // insert your Java method code here
68 }
69
70 /**
71 * Method 'Call cust. by phone'
72 */
73
74 public void phoneCall ()
75 {
76 callCustomer(BY_PHONE);
77 }
78
79 /**
80 * Method 'Call cust. by cell.'
81 */
82
83 public void cellCall ()
84 {
85 callCustomer(BY_CELL);
86 }
87
88 }
|
Code Example 8 - C++ result of multilevel embedding
The C++ class Customer embeds on line 43 class Address whose definition is #included on line 28. Lines 97 and 106 directly derive from section ADJUST (lines 39 and 40) of the entity file. |
| Source code - File "business/LOGIC/Customer.h" |
1 #ifndef __Customer__
2 #define __Customer__
3
4 /*
5 * -----------------------------------------------------------------
6 * Class Customer
7 *
8 * A company/organization, its address, and a contact
9 * person.
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/Address.h"
29 #include "persons/Person.h"
30
31 class Customer {
32
33 public:
34
35 enum enumCallMode {
36 BY_PHONE = 0, // By phone
37 BY_CELL = 1 // By cell
38 };
39
40 private:
41
42 String companyName;
43 Address address;
44 Person contact;
45
46 public:
47
48 /*
49 * Get methods
50 */
51
52 String getCompanyName() {
53 return companyName;
54 }
55
56 Address getAddress() {
57 return address;
58 }
59
60 Person getContact() {
61 return contact;
62 }
63
64 /*
65 * Set methods
66 */
67
68 void setCompanyName( String companyName ) {
69 this->companyName = companyName;
70 }
71
72 void setAddress( Address address ) {
73 this->address = address;
74 }
75
76 void setContact( Person contact ) {
77 this->contact = contact;
78 }
79
80 /*
81 * Method 'Call customer'
82 */
83
84 void callCustomer (
85 int callMode
86 )
87 {
88 // insert your C++ method code here
89 }
90
91 /*
92 * Method 'Call cust. by phone'
93 */
94
95 void phoneCall ()
96 {
97 callCustomer(BY_PHONE);
98 }
99
100 /*
101 * Method 'Call cust. by cell.'
102 */
103
104 void cellCall ()
105 {
106 callCustomer(BY_CELL);
107 }
108
109 };
110
111 #endif /* __Customer__ */
|
The following figure shows the resulting file "customer.html": the embedded entity address in turn embeds entity country.
Figure 2 - HTML result of multilevel embedding
An entity may relate to any other entity within the
SoProTech project that it belongs to. There are two types of
relationships between entities in Sisendel:
Entity
"project.ef"
uses both types of relationships:
It is not possible to directly define arrays of relationships
neither fixed-size, nor dynamic - although a list is logically
equivalent to a dynamic array of links.
It is indirectly possible to construct such arrays by
defining intermediate entities that contain links or
lists, and are in turn embedded as arrays.
As for the embedded entities, the results of using Sisendel relationships
significantly depend on the following factors:
In fact, any mapping of relationships can be freely implemented in the
relevant molds. This approach offers a very high
degree of:
In fact, molds
As previously shown in several examples, a Software Entity,
or entity file, or simply entity, is a textual file
consisting of a fixed sequence of blocks, called sections, that
fully define the different
aspects of a Software Entity, namely:
Each section including CORE, but with the exception
of DEFS and ADJUST, corresponds to a mold group of the same name
within the set of molds used by the SoProTech project.
In fact, the contents of each entity file section instruct
the Sisendel translator on how
it should apply the molds corresponding to that section
when processing the entity file itself.
Mold group DOC does not have an entity section associated
with it: the rationale for this is that generatable DOC
files should actually document
and describe files generated according to the requirements
specified in the other sections.
As previously discussed,
each entity defines a new Sisendel type that can be embedded, or referred
to, by any other entity, independently of its location in the
project tree.
Section CORE is not explicitly named in the entity file, as explained later in the document.
The syntax of Sisendel is rather simple, as
Sisendel is a line-oriented
description language. All important syntax conventions of
entity files are listed in the following table.
| Syntax convention | Description |
|---|---|
| Entity filename | An entity file name must be (on case-sensitive file-systems) a lowercase string of alphanumeric characters without blanks, possibly containing underscores "_", and bearing the suffix ".ef". |
| Physical line | A physical line is a line of text within an entity file. |
| Logical line | A logical line is either one physical line or the concatenation of two or more contiguous physical lines whose last character (except for the last physical line) is the logical line break. |
| Logical line break | A logical line can be split across multiple physical lines using a backslash "\". |
| Identifiers | All identifiers within an entity file (extended entity id, field id's, collection id's, etc.) must be written in lowercase, and may contain underscores, for example like in customer_account. Their translation to more appropriate, language-dependent identifiers, such as CustomerAccount or CUSTOMER_ACCOUNT, takes place within the corresponding molds. |
| Comment lines | Comments are lines starting with a sharp sign "#". Contents of comments is carried over by Sisendel from the entity files and can be used within molds to print it out in the generated files. |
| Labels | Several Sisendel language items, such as entity id, fields, enumeration values, must be associated with a textual label: these labels, delimited by double quotes ", may contain any (readable) character. A mechanism for using double quotes within labels is also provided. |
| Section separators | An entity file consists of the following fixed sequence of sections: CORE, DEFS, DB, LOGIC, UI, ADJUST. The beginning of each section, except for CORE, is marked by the section id in upper case, optionally preceded by a sequence of dashes "-". Section CORE beginning is implicitly marked by the beginning of the entity file. |
| Field indexes | Each field within an entity file is identified by means of a one-character alphabetical index, which is used from within the entity collections to refer to the field itself. |
The syntax rules for sections DB, LOGIC and UI,
are very simple: these sections may only contain ordered
lists of entity fields, called collections. Each collection
consists of two or more logical lines: the first line
specifies an identifier for the collection, and the following
line, or lines, list the indexes of zero, one or more data fields.
A collection must contain the index of at least one data field.
The order and relative positions of the data fields
are important: collections are sequentially processed by the
SoProMach[tm] - the Sisendel translator - when it applies the different
section molds, from left to right and from top to bottom.
Moreover, the row and column position
of each field within the collection is translated to
a set of (x, y) coordinates, which can be used in the molds
to exactly define the position of the implementation of the
various fields
within the resulting generated file. This feature of Sisendel
is particularly useful when designing a graphical user interface
(GUI) in the UI section, as already shown in several HTML
examples earlier in this document.
| Language item | Description | Example |
|---|---|---|
| identifier: | Identifier of the collection being defined. The identifier must appear alone on the source line. | table: |
| collection members | One or more lines, each containing zero, one or more field indexes. | b a c g |
Collections in Sisendel are conventionally referred to by their relative or absolute collection paths: a relative collection path is a string of the form
section.collectionsuch as DB.table, whereas an absolute collection path is a string of the form
entity.section.collectionsuch as employee.DB.table.
The following code example, entity "employee.ef", defines two collections in each one of the DB, LOGIC and UI sections.
Code Example 9 - Collections in Sisendel
Sisendel implicitly defines one collection for section CORE, namely CORE.employee (also referred to as CORE.entity), which consists of all data fields in their definition order, in this example from person to empl_id. Beyond that, this entity explicitly defines six collections, described in the following table. |
||||||||||||||||||||||||||||
| Source code - File "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"
|
The paragraphs that later in this document describe sections DB, LOGIC, and UI, contain the generated files resulting from applying the SoProMach[tm] to entity employee using a small set of sample molds.
The generated files demonstrate how flexibly the concept of Sisendel collection can be adapted to language-specific constructs, ranging from class inheritance in Java[tm], C#, or C++, to primary key constraints in SQL, to form layout design in HTML, and more.
As explained earlier in the document, section CORE lists all of the main characteristics (identity and fields) of a Software Entity.
Each entity is uniquely identified within a SoProTech project by means
of its filename, all in lower case and without the suffix
".ef", independently of its relative position within the
project tree. This filename-id is used from within other
entity files when referring to the entity, such as in
Sisendel link or list relationships, parent-child class
relationships, or plain embedding of entities.
An additional extended entity identifier is provided as the first
non-comment line of an entity file, along with a string
label. This extended id allows entity designers to use
compact file names as short entity identifiers, such as
"dept.ef", and more self-explicative names as extended
entity identifiers, such as department. It is then
up to the project team conventions - implemented by the appropriate
molds - to decide whether to use the latter, or the former, or both.
The entity string label associated with the entity identifier
should be used whenever possible in the molds, typically
in comments within generated source code files, or as a
label on user interfaces.
Finally, any comment between the entity identifier and the
first field is considered by Sisendel as an entity description,
which can also be referred to from the molds and copied into
the corresponding generated files.
The structure of an entity is defined and described by means of
its members, called fields.
Fields are logical lines structured as described in the following table.
| Language item | Description | Example |
|---|---|---|
| index) | Alphabetical index of the field, ranging from "a" to "z", followed by a right parenthesis ")" | a) |
| type | Sisendel type of the field, which may consist of one or more words, depending on whether it is a basic or user type | float |
| identifier | Field identifier, possibly followed by an array cardinality in square brackets. The optional cardinality can be constant (an integer number) or dynamic (the string "dyn") | price |
| label | Human-readable descriptive field label | "Item price" |
One or more comment lines may follow each field definition, and, if present, they are considered by Sisendel as a field description, in exactly the same way as for the entity description discussed before.
The field index serves as a shortcut to the field from within the other sections, in particular from the various collections, and - depending on the field type - from the DEFS section in case further details are required to completely define the field (such as function parameters and return value).
The field identifier and label play for the entity field exactly the same role played for the entity by the entity identifier and label: the field identifier should be used in the molds to generate the language-appropriate identifier at molding time.
The following two code examples show:
Code Example 10 - Fields of "project.ef"
Lines 1-3 define three fields in terms of fields whose definition is imported from library entity strings. Lines 6 shows an example of field description comment, that can be used in molds to carry it over into the generated files. Lines 4, 7, 8 and 9 define fields as references to other entities: in this entity file it is assumed that somewhere in either the project or library tree there are three entity files respectively called "customer.ef", "employee.ef", and "department.ef". |
| Source code - File "proj_fields" |
1 strings.name proj_name "Project name"
2 strings.id proj_id "Project id."
3 strings.description descr "Description"
4 link customer customer "Customer"
5 float budget "Budget (K$)"
6 | Project budget unit is 1,000 dollars
7 list employee team_members "Team members"
8 link employee manager "Proj. manager"
9 link department department "Department"
10 bool internal "Internal"
11 thing plan "Proj. plan"
12 function cur_status "Current proj. status"
13 enum status "Proj. status"
|
Code Example 11 - Library entity "strings.ef"
This entity defines a set of string identifiers that should be standard across one or more projects involving one or more development teams. This approach can ensure consistency for example across all database tables, or middleware messages, or user interfaces, that make use of such common data items as user_id or email. It should be noted that: |
|
|
| Source code - File "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
|
Unlike sections DB, LOGIC and UI, section CORE
does not allow - by syntax rules - to define field collections.
The only collection implicitly defined for CORE is a collection
with the following characteristics:
Background theoretical reason for this peculiarity is that the
CORE features of a Software Entity should represent the
unique and complete identity of the entity itself.
Several previous code examples have already illustrated all
types of field feature definition allowed in section DEFS.
Each definition consists of at least two logical lines,
the first one specifying the index of the field referred to
by the definition, and the others specifying the actual
contents of the definition.
The following paragraphs and tables summarize the syntax for the
different field feature definitions.
A range definition may be associated with a field of type
range or to a field of type float. Conversely, a range
field must have a range definition associated with it,
while a float field may have an associated range definition.
| Language item | Description | Example |
|---|---|---|
| index: | Index of the field being defined. The index must appear alone on the source line | a: |
| min / max | Minimum and maximum legal values for the field | 18/120 |
An enumeration definition must be associated with exactly one field of type
enum. It consists of the index line followed by
one or more logical lines each containing identifiers
and labels for the enumeration values.
By default, Sisendel associates with each enumeration identifier a
numeric value, starting from 0. Alternatively,
each definition may associate a user-defined value
with the corresponding enumeration identifier.
User-defined values can be integer numbers or character constants.
| Language item | Description | Example |
|---|---|---|
| index: | Index of the field being defined. The index must appear alone on the source line | a: |
| identifier | Symbolic enumeration value identifier | first_class |
| label | Human-readable label for the enumeration value | "First class" |
| Language item | Description | Example |
|---|---|---|
| index: | Index of the field being defined. The index must appear alone on the source line | a: |
| identifier | Symbolic enumeration value identifier | first_class |
| value | Decimal integer value to be associated with the identifier | 1 |
| label | Human-readable label for the enumeration value | "First class" |
| Language item | Description | Example |
|---|---|---|
| index: | Index of the field being defined. The index must appear alone on the source line | a: |
| identifier | Symbolic enumeration value identifier | first_class |
| value | Single-character value (between single quotes) to be associated with the identifier | 'F' |
| label | Human-readable label for the enumeration value | "First class" |
A function definition may only be associated with a field of type
function. Purpose of the function definition is to specify
the function signature, that is,
the input parameters and the return value type of the
function.
A function definition consists of the index line followed by
one or more logical lines, each containing
one signature. In most cases, a function definition
will have one signature; additional signatures
may be defined to overload the function interface.
Each function must have at least one signature
definition associated with it. Each signature consists of
a list of input parameters, followed by the
symbolic representation of an
arrow (the string "->"), followed by
the function return value type.
Function parameters and return value type
are specified by means of
field indexes: this implies that they be defined
in the entity fields list of section CORE.
A void list of function parameters is specified
by using a "0" (zero) in place of the
field indexes before the arrow "->".
In the same way, a void return
value is specified by a "0" (zero)
after the arrow "->".
| Language item | Description | Example |
|---|---|---|
| index: | Index of the field being defined. The index must appear alone on the source line | a: |
| input parameters | A list of one or more field indexes, or a 0 (zero) for a void parameter list | c g |
| -> return value type | Representation of an arrow, followed by one index field or a 0 for a void return value | -> e |
The database section of an entity file allows to define how the data related to a given entity should be grouped and managed by a data management system, such as a relational database, or a file system. Section DB will typically contain a definition of the database table and key, or keys, to access the data. Such definitions can be expressed in terms of collections of fields; in fact, the only Sisendel language rule applicable within section DB is the collection definition described in the corresponding paragraph .
The DB mold applied to collections DB.table and DB.pkey
of entity
"company/employee.ef"
produces an SQL file,
containing a script to create a database table for that entity,
as shown in the following
code example.
Code Example 12 - From DB.table and DB.pkey to "employee.sql"
This generated SQL script is derived from collections DB.table and DB.pkey of entity employee. The mapping between the members of DB.table and the SQL source code lines is as follows: |
|
|
|
|
|
|
|
|
| Source code - File "company/DB/employee.sql" |
1 --
2 -- This SQL script created by somusar/SoProMach[tm]
3 --
4
5 create table employee (
6 emplid int not null,
7 lastname varchar(40) not null,
8 firstname varchar(40) not null,
9 emailaddr varchar(60) not null,
10 telephone varchar(40) null,
11 cellphone varchar(40) null,
12 infoage int not null,
13 infossn varchar(40) not null,
14 infonationalitycountry varchar(40) not null,
15 infophotoimgfile varchar(1024) not null,
16 deptdeptid varchar(10) not null,
17 position varchar(40) not null,
18 salary decimal(10,2) not null,
19 constraint pk_employee primary key (emplid)
20 )
21 ;
22
|
The application logic section of an entity file allows to define
how the data and function fields of a given entity should be
grouped within the scope of the application-specific data
processing layer of a software system.
Object classes, as well as
transaction processing data structures and functions, should
be defined within section LOGIC. The same considerations
made for section DB apply here as well:
field collection definitions are the only
Sisendel rule applicable within section LOGIC, thus
class or transaction definitions are to be expressed
as Sisendel collections.
The following code examples have been generated by applying
two simple LOGIC molds to
sample entity
employee, one mold to produce a Java[tm] class source file,
and the other to produce a C++ class definition ".h" file.
Code Example 13 - From LOGIC.class and LOGIC.parent to "Employee.java"
The generated Java class is derived from collections LOGIC.class and LOGIC.parent. Collection LOGIC.class is used to generate Java source code as follows: |
|
|
|
| Source code - File "company/LOGIC/Employee.java" |
1 /*
2 * This Java class generated by somusar/SoProMach[tm].
3 */
4
5 package com.somusar.entdemo.company;
6
7 /**
8 * Class Employee:
9 *
10 * An employee, some related information, and the
11< |