Main Index
PREV
NEXT
|
The 3 Tier architecture in UNIFACE involves several different types of component.
A typical arrangement of these component types is shown in figure 1:
Figure 1 - UNIFACE component types
Within the sample software which accompanies this document there are no examples of Entity Services as I did not have good reason to employ them. An example of a Custom Service is my Audit Object which is activated each time the database is changed - this will write the 'before' and 'after' details of each change to an audit entity.
Communication between Session Services and the database is via the standard I/O operations in the <read>, <write> and <delete> triggers. If Entity (Object) Services are being employed then the standard I/O operations are automatically routed through the relevant service by the UNIFACE kernel.
Communication between Forms and Session Services is via a set of standard operations which pass XML streams between the two components. An XML stream is a data string which is constructed to the XML standard set by the World Wide Web Consortium.
An XML stream contains data in the form of elements. An element can contain data, other elements, or a combination of data and elements. UNIFACE entities are represented as XML elements in XML streams. The fields of an entity are represented as child elements of the entity's element. Inner entities are represented as child elements of the outer entity. An XML stream can contain the data for any number of occurrences of any number of entities.
XML streams do not make a distinction between database and non-database fields, or between fields and entities defined in a component or in an application model.
The structure of an XML stream is governed by a Document Type Definition (DTD). XML streams can be accessed in UNIFACE by means of the following commands:
XMLSAVE XMLvariable, DTDname{, DTDmapping}
- will transfer data from the component into an XML stream.XMLLOAD XMLvariable, DTDname{, DTDmapping}
- will transfer data from an XML stream into the component.RETRIEVE/RECONNECT
- will take occurrences that have just been loaded with XMLLOAD
and attempt to reconnect them to the database using the processing information obtained from the XML stream.The DTDmapping
option allows for differences in element names between the XML stream and the component.
Document Type Definitions (DTDs) are maintained using the DTD Editor which can be accessed from within the Model editor. From the pulldown menu within the Model editor select: GoTo - DTDs. After selecting a DTD name the DTD Wizard allows you to quickly identify the entities and fields within the XML stream.
Elements in an XML stream are either mapped to entities or fields painted in a UNIFACE component. Entity elements are mapped to UNIFACE entities, and field elements are mapped to UNIFACE fields. If there is a difference between the element name in the XML stream and the element name in the UNIFACE component this can be specified in the default mapping option within the DTD.
If the XML stream is required to contain processing information, such as is required to reconnect occurrences to the database, then the relevant attributes must be included in the DTD.
If the DTD contains more than one entity then the relationship between those entities, either side-by-side (siblings) or in a parent/child hierarchy, must be duplicated in the component which is using that DTD otherwise no data can be transferred.
Processing information is not data, it is information about data - whether data is new or already stored in a database, or whether data is valid or nonvalid.
UNIFACE can include processing information in the XML stream, describing the modification and validation status of the occurrences, and also enabling reconnection of the data to its source. These processing attributes are generated automatically by UNIFACE provided that they have been specified in the DTD used by the stream. These attributes are:
Status
- stores the modification status of an occurrence. The following values are allowed:
Id
- is a unique identifier based on the primary key of the occurrence. If an occurrence is new, the value of id is based on the occurrence's internal identifier in the component's data structure.
Checksum
- is a cyclical redundancy checksum (CRC) based on the field values at the time the occurrence was saved into an XML stream. When the XML stream is reconnected to the database, the CRC value is recalculated and compared with the CRC value in the XML stream. The CRC values must match or the occurrence is not reconnected. (A mismatch indicates that the data has been changed in the database since the disconnected record set was created). This results in behavior identical to optimistic locking.Valerr
- if a data validation error occurred while reconnecting data from an XML stream to a database, the validation errors can be written to an XML stream sent back to the calling component.The Status
, Id
, Checksum
and Valerr
attributes are available for each occurrence. The Valerr
attribute is available for each field.
The Status
, Id
and Checksum
attributes are required if the retrieve/reconnect
statement is going to be used to reconnect occurrences to the database.
The Proc functions $occcrc
, $occstatus
, $occproperties
and $fieldproperties
can be used to access processing information loaded from an XML stream.
UNIFACE maps field values to XML elements in the stream using a combination of the following mapping methods:
DTDMapping
(highest priority). This is a mapping structure defined in Proc, as an associative list of element names and UNIFACE field and entity names. For more information, see DTD mapping lists/incldefmap
switch is used.DTD mapping lists map the values of elements in a DTD stream to fields on a component.
Default DTD mapping lists can be defined in the DTD Editor. DTD mapping lists can also be defined in Proc, for use in the Proc statements xmlload
and xmlsave
.
DTD mapping lists are UNIFACE associative lists. Each list item has the following syntax:
"ElementName=TargetName;..."
Where:
ElementName
- is the name of an element in the DTD. ElementName
is case-sensitive.
TargetName
- is the name of a field or entity. The fields or entities do not have to be present on the target component. Values that cannot be mapped to a painted field are ignored. TargetName
is not case-sensitive.
These mapping techniques work in parallel, with local mapping overriding all other mappings for a given element or field, and name matching only being applied to those elements for which no other mapping is defined.
In a three-tier architecture, it is the responsibility of the data layer to communicate with the underlying databases. The other application tiers should not communicate directly with the databases. This implies that:
Data which has been passed to the Presentation layer in an XML stream, modified, then returned to the Business layer can only be reconnected to the database provided that the relevant processing information is contained within the XML stream. This will help determine if occurrences are to be inserted, modified or deleted.
As has been stated in the previous section the Presentation layer components should use non-database entities and should avoid using database entities. Data is provided in the form of disconnected record sets which are retrieved from and returned to Business layer components in the form of XML streams.
Non-database entities can be defined in the following ways:
read
, write
and delete
statements removed from the associated triggers within the Presentation layer components so as to avoid direct connection to the database.read
, write
and delete
statements already neutralised.The disadvantage of using existing entities or entity subtypes is that you cannot alter their structure - you cannot add fields, remove fields or rename fields. You cannot merge entities or split entities, or define entities that do not actually exist. You cannot take a complex physical structure and simplify it for use by the Presentation layer.
If you are going to create new entities just for the Presentation layer it makes sense not to mix them up with the Business layer entities but to keep them in a separate application model. This is what I call the Presentation Application Model or PAM. Any differences between entity and field names between the Business Application Model (BAM) and the Presentation Application Model (PAM) can be dealt with by defining default mapping options in the DTD.
In my methodology I prefer to use a separate application model for the Presentation layer because of the greater flexibility it gives me. A typical example of this is where an entity contains a foreign key to another entity, and in my presentation layer component I need to display fields from both entities. By using a totally separate application model I am able to merge fields from a foreign entity with those of the main entity - it is only the business layer component (session service) that needs to know that multiple entities are involved.
http://www.tonymarston.net |