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.
Code Example 3 - Sisendel user type image
|
The entity image is simply implemented as
a pathname of an image file. It should be noted that:
- Lines 8-9 ensure that any other entity using image in its own database table will embed the pathname of the image file (field image_file), which is the only item of collection DB.table;
- Lines 11-12 define collection LOGIC.class as containing member image_file;
- Line 17 prevents the Sisendel translator from generating a script to create a database table for the images.
|
|
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.
Code Example 4 - Use of the new type image
|
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:
- "customer.sql" is generated from collections customer.DB.table and customer.DB.pkey;
- "Customer.java" and "Customer.h" are generated from collection customer.LOGIC.class;
- "customer.html" is generated from collection customer.UI.full_view.
It should be emphasized that the SoProMach[tm] can automatically
generate, or regenerate, these four files in less than one second on a
regular PC; thus, any change in the entity file
can be reliably, uniformly, and almost immediately
reflected in the generated files.
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.
On the side, lines 13-17 derive from field contact, which
is an embedded person, and the constraint clause of
line 18 corresponds to collection customer.DB.pkey.
Finally, by project convention, database column identifiers
should not contain underscores "_". Such project-wide
conventions are centrally implemented in molds and can be
quickly changed and applied to all generatable files of
all project entities.
|
|
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
|
|
|
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 }
|
|
|
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:
- Simple (one-to-one) relationships, specified in Sisendel using the term link;
- Multiple (many-to-one) relationships, specified in Sisendel using the term list.
Entity
"project.ef"
uses both types of relationships:
- It has simple relationships to entities customer and department: that is, one project is carried out for one customer and is assigned to one company department;
- It has both a multiple and a simple relationship to entity employee, as one project is carried out by more than one team members under the responsibility of one project manager.
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:
- The involved software system layer: a Sisendel link can be mapped to a relationship column in a relational database, as well as to an hyperlink on a web page;
- The language used for the generatable file: a Sisendel list can be mapped to a Collection in Java[tm], as well as to an array of pointers in C;
- Project conventions: a Sisendel link used in a UI collection may be mapped in HTML to either an hyperlink or a push button.
In fact, any mapping of relationships can be freely implemented in the
relevant molds. This approach offers a very high
degree of:
- Productivity;
- Flexibility;
- Consistency
In fact, molds
- Are automatically applied by the high-speed SoProMach[tm];
- Can be changed or refined according to changes or refinements of project requirements and conventions;
- Are mechanically applied to all entities of a software project.
[Previous chapter]
[Next chapter]
[Back to top]
|