skip to main content
OpenEdge Development: AppBuilder
Data-Communication Objects : SmartB2BObjects
 
SmartB2BObjects
The SmartB2BObject helps you make your applications capable of business-to-business communication. It handles transformation between the internal data representation and the emerging standard for inter-business communication, the eXtended Markup Language (XML). Figure 37 illustrates how the SmartB2BObject fits into an application that can communicate with another business over the Internet.
Figure 37: SmartB2BObject in inter-business communications
XML is related to HTML, the HyperText Markup Language of the Web. Both XML and HTML are descendents of SGML, the Standard Generalized Markup Language used in high-end publication editors.
A detailed description of XML is well beyond the scope of this document, but you can find specifications and descriptions in a number of sites on the Web. The standards body for XML, as for HTML, is the WorldWide Web Consortium (W3C), an international organization. The W3C is hosted in the Americas by the Massachusetts Institute of Technology in Cambridge, Massachusetts, USA, in Europe by the Institut National de Recherche en Informatique et en Automatique (INRIA) at several locations in France, and in Asia by Keio University at their Shonan Fujisawa Campus in Japan.
The W3C sponsors several ongoing engineering committees, including the XML Schema Working Group. The consortium’s Web site has information about these working groups, including instructions for joining them if you want to help with their work. The Web site also has primary instructional materials, standards documents, pointers to tools such as schema validators, and links to other sites. Their URL is http://www.w3.org.
XML schema and mapping files
Although two business partners might use an identical set of logical documents, their documents generally have different physical formats and map to databases that are organized differently. Rarely will two businesses use the identical format for their purchase orders, for example, or have identically-named tables and fields. This creates a problem for automatic handling. Although human beings are extremely good at recognizing when two different physical formats are logically equivalent, computers are not. For this reason, some way is needed to transform a logical document from the sender’s local format into the receiver’s local format. The most general solution to this problem is to create a shareable intermediate representation. XML, emerging as an international standard, is well-suited to that role.
XML schema are defined using a notation called “XML Data, subset reduced.” A number of organizations have arisen that act as repositories for shareable schema and there are already schema defined for many common documents. You can discover some of them through the WWW Consortium Web site and others by using a Web search engine.
An XML schema for some logical unit of communication (a purchase order, an invoice, a catalog, etc.) is defined in advance and shared with business partners who will receive that kind of document. XML schema serve the same purpose as database schema—they define how raw data should be interpreted. They deal with form rather than content.
After a schema for a document has been agreed upon, each business creates an additional XML file that describes how to map between that common, shared schema and their own local data format. Typically, different mapping files will be used for inbound and outbound documents, even within a single site.
Once those mapping files have been created and debugged, communication becomes a relatively straightforward operation.
Caution: At present, there is no automatic safeguard against schema version skew. It is possible for a particular schema to be changed without notice, with an updated map file being created only at one end of the communication channel. In that case, miscommunication will certainly occur, possibly in ways that are important but hard to detect. Although you cannot eliminate this problem, you can reduce it by maintaining and checking for version information in any schema you create.
Figure 38 illustrates how the schema, the map file, and the data interact in inter-business messaging.
 
Figure 38: Simple one-to-one XML mapping in data communication
On the originating side (the left side in Figure 38), the value for the Surname (family name) field in the Empl table is Smith. The XML schema specifies a Surname field of type string. The map file relates the XML Surname node to the Empl.Surname field.
The SmartB2BObject would use that mapping to extract the value Smith from the data and insert it into the message. When the message is received (the right side in the figure), the SmartB2BObject there parses the message, encounters Surname, and checks its own map file, where it sees that Surname maps to the Client.FamName field. It then passes the value Smith to the SmartDataObject handling that table.
Note that neither the table nor the field need have the same name on both sides. That is the purpose of XML mapping: to make such differences irrelevant.
Figure 38 illustrated the simplest mapping: an XML field to a database field. Figure 39 illustrates a more complex possibility: deriving a value for the message by filtering local data.
Figure 39: Mapping an XML node to a function
In this example, the node definition in the XML schema is the same as in Figure 38: Surname, defined as type string. Here, though, there is no surname field in the Empl table. The whole name is stored as a single string. The mapping in this case is to a dedicated function FamilyName() that reads the Name field and returns the surname substring.
Where does that dedicated function come from? You create it.
You can create mappable procedures and functions within the SmartB2BObject itself, or in the SmartBusinessObject or SmartDataObject that cooperates with the SmartB2BObject. In general, good programming practice suggests that you put special procedures and functions inside the object to which they are most closely related. In the illustrated case (Figure 39), that would be the SmartDataObject, since a FamilyName() function would be the logical equivalent of a calculated field.
Mapping options
Mapping is like translating between spoken languages. It can be simple or difficult depending on the complexity of the original document and your skill at preserving the underlying meaning.
Caution: No type-checking is performed during the mapping process. You must ensure that the values you produce by mapping or conversion are appropriate and correct.
You have a number of mapping options to aid you in your document conversion. You can choose to map a schema node to:
*A column being managed by a data-access object.
*A function you created in the SmartB2BObject itself.
*A procedure you created within the data-access object.
*A function you created within the data-access object.
*A whole data-access object.
These options are discussed more fully in the following sections.
Mapping to a column
This is the simplest and probably the most common mapping. You can use it whenever a column in the data stream corresponds directly to a schema element.
Calculated fields/columns can complicate matters. On the outbound side, mapping a calculated column is identical to mapping an ordinary column. However, since calculated fields have no physical existence in a database, you would have to write special code to make sense of an inbound mapping. Usually, calculated fields are read-only; writing them in a meaningful way requires that you handle the result as a special case, decomposing and folding it back into the original fields in some way that fits your business context.
Mapping to a function in the SmartB2BObject
If you need to transform or convert a column value in some general way before sending/storing it, you can create a function to do that inside the SmartB2BObject itself. For example, you might create a function to convert dates to some special format, or present an integer value in some unusual base. The Mapping Tool will display any such functions as options when you elect to map to a column.
These conversion functions always have a single parameter:
*For inbound documents, the value of the message element is passed as the parameter and the return value of the function is stored into the data field.
*For outbound documents, the situation is exactly opposite: the data field is passed as the parameter and the return value of the function is used as the message element.
Mapping to a procedure in the data-access object
When you map an XML node to a procedure, you are actually mapping to the procedure’s parameter. The parameter must be an INPUT parameter for inbound documents and an OUTPUT parameter for outbound documents. It must also be the only parameter. You must handle all ABL data operations inside the body of the procedure.
Mapping to a function in the data-access object
When you map to a function, the exact mapping depends on the direction:
*For inbound documents, you are mapping the schema node to an INPUT parameter. You must handle all assignments to the data field within the body of the function; the return value will be discarded.
*For outbound documents, you are mapping the return value of the function to the schema node. These functions can have no parameters. Handle all data reads within the body of the function.
Mapping to a whole data-access object.
Mapping a whole object to a schema node has a different meaning depending on whether you are creating an inbound or an outbound map. On the outbound side, the meaning is an implied one: iteration.
Consider the subtree example shown:
The fields custnum, name, state, and so forth have obvious mappings to fields in the Customer table. To map those fields to these nodes, you must identify as a resource the SmartDataObject that supplies records from the Customer table.
If the schema allows multiple instances of the Customer element to be generated, and you map the object itself to the Customer node here, then the SmartB2BObject treats that as a request to fetch all Customer records as part of building the message body. It will loop through all Customer records, extracting values for each of the mapped fields (custnum, name, and so forth) and creating XML for them.
The net result of that loop will be multiple Customer record elements, explicitly laid out in the message body. It might look something like the following, if the only fields mapped were custnum and name:
 
<Customer>
  <custnum> 1 </custnum>
  <name> Smith </name>
</Customer>
<Customer>
  <custnum> 2 </custnum>
  <name> Garcia </name>
</Customer>
<Customer>
  <custnum> 3 </custnum>
  <name> Hardingfele </name>
</Customer>
Which means that, on the inbound side, no loop is required—simply going through the message in a linear way will traverse all included elements.
On the inbound side, the result of processing the incoming XML is typically operations on a database. When you elect to map a data object to an element, you must identify what sort of operation is desired or acceptable:
*Update (may exist) — Any particular record need not exist. If it does exist, it will be updated and if it does not exist, it will be created.
*Update (must exist) — The record must exist and will be updated as part of the message-consuming process. If the record does not exist, the data handler will report an error.
*Create only — The record must not already exist; it is created as part of the message- consuming process. If the record already exists, the data handler will report an error.
*Delete — The record must exist; it is deleted as part of the message-consuming process. If the record does not exist, the data handler will report an error.
*Find — This operation is used for positioning the current-record pointer in the database.
Note: It is also possible to identify the operation within a node of the message itself. Exactly how this is to be done is not well-defined and may vary across document schema. If you face this situation, you must write code to handle it as a special case.
To continue the example: if on the inbound side you map the Customer object to the Customer element with a type of Create, then every time the receiving SmartB2BObject sees the <Customer> token in the received message, it will build a Create request using field data from <custnum>, <name>, and so forth. When it reaches the </Customer> token, it will forward the request to the local SmartDataObject that manages that table.
Note that, in this example, Customer cannot be the root node of the schema tree if you intend to generate multiple records; XML only allows one root node. If Customer were the root node, only data from the current record would be transformed into XML.
However, if Customer is not the root node of the schema tree, then all Customer records will be processed. If you want only a subset of all records to be used, you must take steps to ensure that only those records appear in the data stream. Consider using a SmartFilter for that purpose (see the “SmartFilters” section for details).
Caution: If you map an object to some field/column that does not necessarily have unique values across all records, Find, Delete, and Update operations will act on the first acceptable record found. That might not be what you intend or desire.
XML schema Mapping Tool
Every time the SmartB2BObject converts some document to or from XML, it must read the logical associations from a map file. You or the user of your application must create each such map file specifically for a particular document schema and direction (inbound or outbound). This can be a non-trivial programming task. Progress Software provides an editor—the XML Mapping Tool—to make that task easier.
Figure 40 shows the Mapping Tool’s window.
Figure 40: XML Mapping Tool window
The Mapping Tool window is divided into two spaces—a tree view on the left and a tab control with four tabs on the right.
The tree view displays the current state of the map file. Each line represents a mappable element of the document. As you make mapping choices, the tree view changes to reflect them. When every node displays a mapping, your map file is complete.
The four tabs on the right contain the editing interface:
*The Map tab is where you will do most of the mapping work.
*The Schema tab provides read-only information about the current schema file.
*The Source tab offers a read-only view of the raw schema source.
*The Object tab allows you to identify the local SmartObjects to use when mapping nodes.
Starting the XML Mapping Tool
You can start the XML Mapping Tool in either of two ways:
*Click the tool icon at the end of the PRO*Tools toolbar:
When the Mapping Tool window opens, choose FileOpen and select one of the three types of files the mapping editor understands. Those files are:
*Outbound map file — Identified by the filename extension .xmp (XML Map for Producers). This file is used to transform outgoing data from the local internal representation into XML format for transmission.
*Inbound map file — Identified by the filename extension .xmc (XML Map for Consumers). This file is used to transform incoming data from the XML representation into the local internal format for processing and storage.
*XML schema file — Identified by the filename extension .xsd (XML Schema Document). This file represents the generic, standard, nonproprietary document. It is used by all parties as the basis for creating their inbound and outbound map files. You cannot edit a schema file using the XML Mapping Tool.
*Choose FileOpen in AppBuilder and select a map or schema file. AppBuilder will automatically call the Mapping Tool on your behalf.
Note: The XML Mapping Tool only supports schema files that conform to the W3C specification. It does not attempt to handle other formats such as Microsoft’s or BizTalk’s. Nor does it handle the older Document Type Description (DTD) files.
Creating an XML map file
Use the Mapping Tool to create a map file.
To create a map file:
1. Start the Mapping Tool and select the SmartObjects that will handle this class of document.
2. Work through the fields—nodes— of the document in an orderly way, mapping each one to the corresponding object, database field, or transforming routine.
Selecting SmartObjects for mapping
The SmartB2BObject always transforms data on behalf of some other object. You must identify at least one such object—typically a SmartDataObject or SmartBusinessObject—before you can begin mapping nodes.
To map SmartObjectsWriter:
1. Choose the Object tab. The view changes, as shown:
2. Click Add. Select an object that can serve as a DATA-SOURCE or DATA-TARGET, depending on the type of map file you are creating. Its ObjectName property will appear in the fill-in and its filename will appear in the list box.
Note: You can edit any ObjectName here, but no two listed objects can have the same ObjectName. If you change an ObjectName, the new name must be locally unique (in other words, unique within the list you are creating here).
3. Repeat Step 2 until you have identified all the objects you will use.
Note: If you intend to use conversion functions that reside in the SmartB2BObject, you must add that object to this list as well.
If you make a mistake when adding an object, select it in the list and click Remove. Note that you can remove an object from the list at any time. Even if you have already mapped nodes to the object, the mappings will go away cleanly if you remove the object name from the list.
4. Select the mode of this map file: inbound (consumer) or outbound (producer).
5. Click Browse and identify the SmartContainer that holds the SmartB2BObject that will use this map file. You can omit this step if this is the only document type your application will produce/consume.
6. Choose FileSave to save your work.
You are now ready to begin the mapping process itself.
Mapping schema nodes
As the SmartB2BObject parses some logical document, it consults the map file you created for that document type. That map file must contain a mapping association for every element of the document. As the SmartB2BObject identifies an element in the document, it creates a transformation based on the association you supplied.
To create an association:
1. Select a node in the tree view. Click the Map tab, if necessary:
2. Pull down the Object list and select the object that will supply the association for this node:
3. Select the appropriate radio button to refine the association. You can choose to map the node to:
*The whole object, if you intend to loop through multiple records (outbound side) or to CREATE, FIND, or DELETE the node, or UPDATE it or its children (inbound)
*Some particular field supplied by the object, if the node does not have children
*Some procedure or function, if the node does not have children
See the “Mapping options” section for more information
4. The display changes to reflect your choice, as shown:
Complete the association by selecting the exact mapping (see the “Mapping options” section for more information):
*If mapping the whole node in an inbound document, select the action to be performed (Update-may exist, Update-must exist, Create only, Delete, Find):
*If mapping to or from a column that you will filter through a SmartB2BObject function, select the column identifier before you select the function identifier:
*If mapping to a procedure, or to a function not in the SmartB2BObject, select it from the list that appears after you choose the radio button.
Creating a master SmartB2BObject
The SmartB2BObject is supplied for your use in two forms: a template for creating custom master objects and a precompiled master from which you can create generic instances. Unlike other template-based SmartObjects, creating a custom master SmartB2BObject does not involve a wizard.
To create a new master object:
1. Click SmartB2BObject in the Object Palette.
2. When the Choose dialog box appears, click New.
Note: You could also start the process by choosing FileNew and selecting the SmartB2BObject item from the list, or by right-clicking the icon in the Object Palette and selecting New SmartB2BObject from the menu that appears.
3. The new SmartB2BObject master appears immediately. Select it, open the Section Editor, and add all the code needed to complete this custom master.
4. Choose FileSave and give the new master a descriptive filename. Note that SmartB2BObject filenames conventionally begin with sbb.
The new master object is now available for your use.
Creating and placing a SmartB2BObject instance
Creating a SmartB2BObject instance is much like creating an instance of any other SmartObject.
To add a SmartB2BObject instance to your organizer workspace:
1. Click the SmartB2BObject tool icon in the Object Palette. When the Choose dialog box opens, select the appropriate master and click OK.
Note: To select the dynamic object, right-click the tool icon instead. The dynamic object is listed last in the menu that appears.
2. The SmartB2BObject has no run-time representation, so you can position it anywhere in the workspace. For your future convenience, consider selecting a spot that will otherwise remain empty. When you have selected a spot, click to release. The design-time representation appears:
3. AppBuilder opens an Advisor window if it finds opportunities to create SmartLinks to other objects. Accept the Advisor's recommendations, if they seem appropriate.
4. Configure the instance. Save your work.
Configuring a SmartB2BObject instance
If you have already created the map file, configuring a SmartB2BObject instance is straightforward. To begin the configuration process, right- click the instance and choose Properties from the context menu. The Property Sheet dialog box appears:
To configure an instance
1. Change the object identifier to more clearly reveal the role of this object in your application.
2. If you wish to use this object as a placeholder, set the Parameterize as Variable check box. For information about using instances as placeholders, see the “Creating a SmartObject placeholder” section.
3. Click OK and save your work.
You are now ready to configure the instance properties. The SmartB2BObject’s instance properties vary depending on whether the object will process incoming or outgoing documents. In either case, begin by clicking the menu button and choosing Instance Properties from the menu that opens.
Outgoing instance properties
If you have already linked this object to a SmartProducer, the dialog box should open with the Producer tab selected, as shown:
If it is not selected, select it now.
To configure outgoing properties:
1. At a minimum, configure the following fields to use XML:
*XML Mapping File — Type in the path to the file that this object will use when transforming documents.
*Destination — The logical identifier of the outbound document’s destination. At present this must be a queue or topic served by the Progress SonicMQ system.
If you prefer to use a DTD (Document Type Definition) file, set the Use DTD toggle. This will enable the Public ID and System ID fields for you to specify:
*Public Id (DTD) — (Optional) Enter the global public identifier of the DTD document.
*System Id (DTD) — (Mandatory) Enter the path to the actual DTD file. Click the Browse button if you wish to search for the file.
2. Examine the following fields and change those that do not meet your needs:
*Reply Required — Defaults to cleared. Setting this check box will notify recipients that you wish a reply sent to you whenever they receive a document of this type. You must add code to handle these replies.
*Reply Selector — If you wish to filter incoming replies according to values in reply-header fields or properties, enter the expression here. The SmartProducer object will perform the test on incoming replies and discard from the inbound Queue/Topic any messages that fail the test. Example: company_name = "Smith" AND priority > 4. A reply from the Smith company with priority of 4 or less would be discarded without notice. The syntax is a subset of the syntax defined in SQL-92.
3. If this SmartB2BObject will create different documents from the same data stream, or send to different real-world or JMS destinations, click Multiple Producers. Additional fields come into view, as shown:
4. For each document type/destination pair, fill in the fields identified in Step 1 and Step 2.
5. To specify where to find the name reference at run time, set the Document Name Data check box. Three additional fields activate themselves. Change their values as appropriate:
*Data Object — Select the SmartDataObject or other data-handling object that handles the data for the new document type.
*Column, Function — Defaults to Column. Selecting Function means that the Document/Direction Name value is returned by a function in the data object rather than by one of its columns.
*Column/Function — The label on this fill-in reflects the current radio-button selection. Select the column or function in the data object that will return the Document/Direction Name.
6. Click Save to add the new document information to the list in the browser widget.
Note: If you decide not to add this entry, click Cancel instead of Save. If you decide you made a mistake in saving an entry, click Delete.
7. To add an additional entry, click Add and repeat Step 4 through Step 6.
8. When you have added all the document types/destinations you desire, save your work.
Incoming instance properties
If you have already linked this object to a SmartConsumer, the dialog box should open with the Consumer tab selected. If not, select it now:
To configure this object for consuming:
1. Identify the mapping file.
2. Save your work.