Engine Demonstration #4

[ engine demonstrations | engine overview | imnmotion.com | Stephen W. Cote ]

Engine Demonstration #4 is Part #1 in a short series of demonstrations on using Engine to create a shopping transaction. A shopping transaction is being defined as a customer browsing or searching through a list of products, selecting ones they want by adding them to a shopping cart, and making the purchase. Part #1 covers creating an engine configuration for querying and displaying the product list.

The files required for this demonstration are as follows:

The purpose of this demonstration is to retrieve XML representing a list of products and transform that XML with an XSL template on the client. In Demonstration #3, a generic object-definition was defined for importing XHTML. For this demonstration, that definition will be slightly altered and expanded.

It makes sense to define a few static paths with variant parameters since the goal is to query a product list, which ostensibly is retrieved from a dynamic source, but some of whose contents may be cached. One approach to achieving the desired result is using ORA values in the query string mostly because it is the path of least resistence from within the declarative configuration file. Remember that an ORA value, or Object Request Alias, is nothing more than a tokenized value that is used to reference objects and properties during runtime from the engine service context. The object-definition used for this demonstration is called import-txml, for import and transform xml. Since XHTML will be returned from the transformation, an abstract html-fragment definition is also defined.

If you see the text Engine Loaded in the following block, then the demonstration succeeded. If the engine is not started text does not vanish, you may be using an unsupported browser or there may be a bug in the software.

engine is not started

The Engine for Web Applications should start almost immediately. If this message does not disappear, there may be a bug with the software, a connectivity problem to the server, or you may be using an unsupported browser.

Engine Configuration XML

The following XML is used to create one of the three configurations that use the import-txml implementations. One customization to the transformNode function, which is the constructor for this definition, is that it embeds any query string name/value pairs into the XML document element. Therefore, the ORA value %ora:eid% might be swc.ocj.engine_1, and that value would be set as an attribute with the name eid. This customization was made make it easy to pass parameters to the XSL without implementing an additional interface.

<page-configuration id = "demonstration_4:view_product">
   <h2>Browse Product Categories</h2>
   <import-txml
      id = "import-sxml-product_list_1"
      src = "/path/product_list.jsp?eid=%ora:eid%&pid=%ora:data_variant%"
      xsl_id = "import-sxsl-item_view_1"
      xsl = "/path/product_viewitem.xsl"
	/>
</page-configuration>

The two ORA values, %ora:eid% and %ora:data_variant%, represent the internal id of the engine object, and a data variant which will be set in a static function. Remember that ORA values used for parameters are not tokenized with percentile characters.

Unlike the object-definition for import-xml in Demonstration #3, the definition for import-txml will invoke a different constructor, with a different set of parameters. Also, where Demonstration #3 defined an abstract import-data definition for translating the XML into XHTML, this demonstration will use a slightly more generic html-fragment name, but which is otherwise identical.

<object-definitions>

   <definition id = "import-txml">
      <implementation context-switch = "1" context-path = "/">
         <package pid = "org.cote.js.xml" />
         <constructor name = "transformNode">
            <param value="ora:src_attr" />
            <param value="ora:xsl_attr" />
            <param value="ora:integer_0" />
            <param value="ora:id_attr" />
            <param value="ora:xsl_id_attr" />
            <param value="ora:integer_1" />
         </constructor>
      </implementation>
   </definition>

   <definition id = "html-fragment">
      <implementation abstract = "1" />
   </definition>

</object-definitions>

A number of import traits about the import-txml constructor, and the transformNode function, are that it accepts path references in lieu of object references. However, this enforces a synchronous request for the XML. To improve performance, the DOM will be cached based on the specified id for either the XML or the XSL. It is important to understand that the in-memory relies upon the correct use of the request id in order for the cached DOM to be successfully retrieved.

Client Javascript

Finally, a static function is defined on the page to process links generated from the XSL. While the engine framework allows developers to make really innovative relationships between data and the user, such as with Wire Link configurations, the purpose of using a simple static function is to show that the data may or may not be bound to the engine framework. So, this demonstration could be (but isn't) architected for unsupported browsers without having to make changes to the server-side application.

function demonstration_product_view(engine_id, product_id, item_id){
   var oEngineService = org.cote.js.engine.EngineService,
      oMessageService = org.cote.js.message.MessageService
   ;
   
   var oEngine = oEngineService.getEngine(engine_id);
   
   if(!product_id) product_id = 0;
   if(!item_id) item_id = 0;
   
   if(oEngine){
      /* DataVariant is an array of variant data */
      oEngine.setDataVariant(1, product_id);
      oEngine.setDataVariant(2, item_id);
      oEngineService.applyConfiguration(
         oEngine,
         (product_id?
            (item_id?"demonstration_4:view_item":"demonstration_4:view_product")
            :
            "demonstration_4:list_product"
         )
      );
   }
   else{
      oMessageService.sendMessage("Invalid engine id '" + engine_id + "'","200.4",1);
   }
}