This document covers the following topics:
The page generation is the process of transferring an XML layout definition into an HTML/JavaScript page. It is automatically executed inside the Layout Painter when previewing a layout. It can also be called from outside.
A generator program
(com.softwareag.cis.gui.generate.HTMLGenerator
) is
receiving a string which contains the XML layout definition. The generator
program parses this string with an XML parser and as a consequence processes the
string tag by tag.
The generation of HTML pages is done in two steps:
Macro Execution
First, each tag of the XML layout is checked if it is a so-called
"macro tag". A macro tag is a tag which does not produce
HTML/JavaScript output itself but which
itself produces XML tags. Imagine a control rendering an address input: this
control is using existing controls in order to create some defined output area
representing an address. The HTML/JavaScript
is not produced by the address control directly - the address control
internally creates other controls (such as fields or buttons) which themselves
produce corresponding HTML/JavaScript
code.
The execution of macro tags is recursively done until no macro tag is contained in the XML layout anymore; that is, macro tags themselves can internally use macro tags.
HTML Generation
After having executed the macros, the rendering of HTML/JavaScript
is started. This is done by calling
corresponding tag handlers for each tag. A tag handler is a Java class and is
applied to the corresponding tag via naming conventions. The HTML generator
instantiates objects of a tag handler class for the tags and calls
corresponding methods of these tag handlers.
Each tag handler is called via a defined interface
(com.softwareag.cis.gui.generate.ITagHandler
) and
can
contribute to the generation process. All tag data, including the properties
from the layout definition, is passed to the tag handler. In addition, a string
with the current HTML/JavaScript is passed and the tag handler can add its
control-specific HTML/JavaScript to this HTML/JavaScript string.
A tag handler instance is called at three different points of time by the generator:
when the tag is starting (for example, the generator finds "<page…>"),
when the tag is closing (for example, the generator finds "</page>"),
when the generator creates a defined JavaScript method which is called at runtime in the browser when the page is loaded.
It is now the task of the tag handler to create HTML/JavaScript statements at the right point of time.
As described above for the HTML generation, control-specific tag handlers are called. The macro execution is either completely done based on XML definitions (see Creating Macro Controls Out of Existing Controls) or you can also implement a specific macro tag handler. This macro tag handler is then called during the macro execution. In case the macro execution is completely done based on XML definitions, a general macro tag handler is used internally.
Macro tag handlers and tag handlers are Java classes
which implement specific interfaces. The corresponding classes are applied to
the tags via the following naming convention: for a tag
<mytag>
, the corresponding Java class must have the name
"MYTAGHandler".
The following topics describe the tag handler and the macro tag handler interfaces in more detail:
The interface
com.softwareag.cis.gui.generate.IMacroTagHandler
contains two methods which represent the different points of time when the
generator calls the tag handler during the macro execution phase.
package com.softwareag.cis.gui.generate; import org.xml.sax.AttributeList; import com.softwareag.cis.gui.protocol.ProtocolItem; public interface IMacroTagHandler { public void generateXMLForStartTag(String tagName, AttributeList attrlist, StringBuffer sb, ProtocolItem pi); public void generateXMlForEndTag(String tagName, StringBuffer sb); }
Detailed information about the methods can be found inside the Javadoc documentation which is part of your NaturalONE installation. See also Developing Java Extensions in the Ajax Developer documentation.
The interface
com.softwareag.cis.gui.generate-ITagHandler
contains
three methods that represent the different points of time when the generator
calls a tag handler during the HTML generation phase.
package com.softwareag.cis.gui.generate; import org.xml.sax.AttributeList; import com.softwareag.cis.gui.protocol.*; public interface ITagHandler { public void generateHTMLForStartTag(int id, String tagName, AttributeList attrlist, ITagHandler[] handlersAbove, StringBuffer sb, ProtocolItem protocolItem); public void generateHTMLForEndTag(String tagName, StringBuffer sb); public void generateJavaScriptForInit(int id, String tagName, StringBuffer sb); }
Detailed information about the methods can be found inside the Javadoc documentation which is part of your NaturalONE installation. See also Developing Java Extensions in the Ajax Developer documentation.
A tag is processed by the generator in a certain way that is now described for the HTML generation phase. (The macro execution phase is processed in a similar way.)
The generator finds the tag, reads its properties and assigns an ID. The ID is unique inside one page.
The generator creates a new instance of the tag handler which is responsible for processing the tag.
The generator calls the
generateHTMLForStartTag
or
generateXMLForStartTag
method correspondingly. It passes the list of properties,
the string buffer which represents the HTML/JavaScript or XML string
correspondingly and a protocol item in which the tag handler can store
further information.
For tag handlers only: The
generator calls the generateJavaScriptForInit
method.
It passes as main parameter a string representing the method body of the
initialisation
method. You can append JavaScript
statements to this string.
(If the generator finds tags below the current tag, these tags are processed in the same way now.)
The generator finds the end tag and calls the
generateHTMLForEndTag
or
generateXMLForEndTag
method correspondingly.
The following image illustrates the call sequence for tag handlers:
Be aware of the following:
There is one instance of a corresponding tag handler per tag. If
there are three button definitions inside a layout definition, then during
generation there are three instances of the
BUTTONHandler
class.
There is one instance of a protocol item which is passed as parameter per tag. Each tag has its own protocol item. All the protocol items are collected at generation point of time to form one generation protocol.
There are certain interfaces which extend the framework for specific situations:
com.softwareag.cis.gui.generate.IMacroHandlerWithSubTags
- this is an extension of IMacroHandler
and provides the
possibility to also receive subtags of a tag.
com.softwareag.cis.gui.generate.ITagWithSubTagsHandler
-
this is an extension of the ITagHandler
interface and
provides the possibility to also receive the subtags of a tag.
com.softwareag.cis.gui.generate.IRepeatCountProvider
and
com.softwareag.cis.gui.generate.IRepeatBehaviour
- these
interfaces are responsible for controlling a special management for the REPEAT
processing, which you use, for example, inside grids (ROWTABLEAREA2).
You do not need to know anything about these extensions to create your first controls. Documentation is provided inside the Javadoc documentation. See also Developing Java Extensions in the Ajax Developer documentation.
The library concept is responsible for defining the way how the generator finds a tag handler class for a certain tag. There are two situations:
The generator finds a tag without a ":"
character. This indicates that this is a control from the Natural
for Ajax product - the according tag handler is found inside the
package com.softwareag.cis.gui.generate
, the class name
is created by converting the tag name to upper case and appending
"Handler".
For example, if the generator finds the tag
"header", it tries to use a tag handler class
com.softwareag.cis.gui.generate.HEADERHandler
.
The generator finds a tag with a ":"
character, for example, demo:address
. This indicates that an
external control library is used. There is a central configuration
file (<installdir>/config/controllibraries.xml)
which contains the external control library names and the corresponding Java
package names. Besides this central configuration file, also corresponding
configuration files on the user interface level are supported. This is
explained later. After having found the package name, the class name
is built in the same way as with standard Application Designer controls.
For example, if the generator finds the tag demo:address
and in the configuration file the demo prefix is assigned to the package
com.softwareag.cis.demolibrary, then the full class name
of the tag handler is
com.softwareag.cis.demolibrary.ADDRESSHandler
.
What happens if the generator does not find a valid class for a certain tag? In this case, it just copies the tag of the layout definition inside the generated HTML/JavaScript string. Via this mechanism, it is possible to define, for example, HTML tags inside the layout definition which are just copied into the HTML/JavaScript generation result.
When writing your own controls, be sure to use a tag
name with your own prefix (such as test:mycontrol
) and use your
own Java package name which must not start with
com.softwareag
. The tag names without prefixes and the
Java package com.softwareag
are reserved for the Natural for Ajax
product.
A control library is a Java library containing
ItagHandler
/IMacroTagHandler
implementations. The corresponding
.jar or .class files can be copied
either to the central WEB-INF/lib or
WEB-INF/classes directory of the
cisnatural web application, or they can be copied to the
./appclasses/lib or
./appclasses/classes subdirectory of a user interface
component.
The central control file for configuring control libraries in your installation is the file <webappdir>/cis/config/controllibraries.xml. An example of the file looks as follows:
<controllibraries> <library package="com.softwareag.cis.demolibrary" prefix="demo"> </library> </controllibraries>
Each library is listed with its tag prefix and with the package name in which the generator looks for tag handler classes.
As an alternative to this central control file, you can have a file ./cisconfig/controllibraries.xml in your user interface component (for example, njxdemos/cisconfig/controllibraries.xml). The format of this file is identical to the central control file controllibraries.xml.
The normal binding concept between a page and a corresponding class is:
Controls refer to properties and methods.
For pages implemented with Java,
properties and methods are
directly implemented as
set
/get
methods or as
straight methods inside the adapter class.
As you might already have read in the part Binding between Page and Adapter of the Special Development Topics (part of the Application Designer documentation), the binding is much more flexible. You can define hierarchical access paths for both methods and properties.
Note:
The Application Designer documentation is included in
the Natural for Ajax distribution package.
For pages implemented with Natural, properties and methods are mapped to an internally used XML representation of the data. The Service Data Objects technology (SDO) is used for manipulating the XML internally (see also http://download.oracle.com/otndocs/jcp/sdo-2_1_1-fr-oth-JSpec/). The XML is then bound to fields and events in the generated Natural adapter.
If you do not delegate the data binding to already existing controls, you need to call specific methods in your handler class which add the corresponding data structures to the SDO. The custom control examples in the Natural for Ajax demos contain corresponding guidelines.
For complex bindings, you sometimes need to implement a corresponding
binding class. A binding class is a Java class which extends the class
com.softwareag.cis.adapter.ndo.NDOCustomControlInfoBase
.
You sometimes use a binding class if you want to implement some control
functionality which is not appropriate to be implemented in the JavaScript
layer. There is also a naming convention for these binding classes. For a tag
demo:address
, the name of the binding class would be ADDRESSInfo.
The custom control examples in the Natural for Ajax demos contain corresponding
guidelines.
Once having created new controls, you want to use them inside the Layout Painter. The Layout Painter is configured by a set of XML files.
The files with the name editor_*.xml are used to extend the Layout Painter with your own custom controls. These editor_*.xml files can either be located centrally in <webappdir>/cis/config/ or in a subfolder cisconfig of a user interface component.
There is a central file editor.xml which defines the central controls that come with the Natural for Ajax framework. For each control, the properties and how the control fits into other controls is defined. In addition, data type definitions to provide value help for the properties are defined inside this file.
In short: editor.xml controls the way in which controls are presented inside the Layout Painter.
When creating new controls, you want to integrate your controls into the Layout Painter, that is, you want to register them inside editor.xml as well. Instead of letting you directly manipulate editor.xml, there is an extension concept - in order to keep your definitions untouched by release upgrades. Again naming conventions are used: for a control library named "demo", you would define your controls in a file with the name editor_demo.xml. This means that you will have one editor_*.xml file per control library.
Have a look at the editor_demo.xml file:
<!-- DEMO:ADDRESSROWAREA2 --> <tag name="demo:addressrowarea2"> <attribute name="addressprop" mandatory="true"/> <protocolitem> </protocolitem> </tag> <tagsubnodeextension control="pagebody" newsubnode="demo:addressrowarea2"/>
In this example, a new control demo:addressrowarea2
is
defined:
It provides one property
addressprop
.
It can be placed into the existing Application Designer control
pagebody
.
Or have a look at the following section:
<!-- DEMO:ADDRESSROWAREA3 --> <tag name="demo:addressrowarea3"> <attribute name="addressprop" mandatory="true"/> <taginstance> <rowarea name="Address"> <itr> <label name="First Name" width="100"> </label> <field valueprop="$addressprop$.firstName" width="150"> </field> </itr> <itr> <label name="Last Name" width="100"> </label> <field valueprop="$addressprop$.lastName" width="150"> </field> </itr> <vdist height="10"> </vdist> <itr> <label name="Street" width="100"> </label> <field valueprop="$addressprop$.street" width="300"> </field> </itr> <itr> <label name="Town" width="100"> </label> <field valueprop="$addressprop$.zipCode" width="50"> </field> <hdist width="5"> </hdist> <field valueprop="$addressprop$.town" width="245"> </field> </itr> <vdist height="10"> </vdist> <itr> <hdist width="100"> </hdist> <button name="Clear" method="$addressprop$.clearAddress"> </button> </itr> </rowarea> </taginstance> <protocolitem> <addproperty name="$addressprop$" datatype="ADDRESSInfo" useincodegenerator="true"/> </protocolitem> </tag> <tagsubnodeextension control="pagebody" newsubnode="demo:addressrowarea3"/>
The control demo:addressarea3
has the following
features:
It provides one property
addressprop
.
It contains the macro XML (between <taginstance>
and </taginstance>
) for building the control out of existing
controls.
It binds to an address property of type
ADDRESSInfo
(between
<protocolitem>
and </protocolitem>
).
It can be positioned below the pagebody
control.
Whenever possible we recommend to use the Control Editor to create and edit the editor_*.xml files.
Note:
If you are working with NaturalONE, see
Ajax
Developer in the NaturalONE documentation for details on
using the Control Editor. If you are working with the standalone version of
Natural for Ajax, see Development Workplace in the
Application Designer documentation, which is included in the Natural for Ajax
distribution package, for details on using the Control Editor.
When defining new controls, there are the following resources:
controllibraries.xml - to define control library prefixes and their binding to a certain Java package holding control implementations.
editor_*.xml - to define the controls and how they fit into existing controls.
IMacroTagHandler
- implementations that
transfer XML control definitions into other XML control definitions.
Remember: Implementing your own macro tag handler is
optional. If a control does not have its own macro tag handler, a general macro
tag handler is used internally.
ITagHandler
- implementations that transfer
XML control definitions into HTML/JavaScript.
NDOCustomControlInfoBase
- base class to
implement complex data binding or control functionality for execution at
runtime.
The next section contains examples for building macro controls and new controls.