Defining the business model in XML
Explains how to create dynamic classes by describing them in an XML file that will be loaded at runtime.
Explains how to create a dynamic class in XML and describes the notions of inheritance, attribute types, and type conversion.
Explains how to extend a predefined class in XML.
Describes the two methods for loading a business model: at application start up or from a data source.
Defining a dynamic class in XML
The XML file may be loaded at the beginning of the program or at a later stage. In the same way as you can load a model from a file, you can also load the corresponding data from a file. You will find an example of a model and the corresponding data defined in the same file in
Adding business objects from JavaBeans.
The example below shows how to describe the dynamic classes Event and Alarm in XML format. These classes will be created when the XML file is loaded.
The
Event class has the
ID attribute of type
string. The
Alarm class is a subclass of the
Event class that has two attributes,
PerceivedSeverity, of type
String, and
Acknowledged, a Boolean attribute that defaults to
false. The
Alarm class inherits the
ID attribute from the
Event class. For details, see
Inheritance.
How to define dynamic classes in XML
<classes xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation = "ilog/cpl/schema/model.xsd">
<classes>
<class>
<name>Event</name>
<attribute>
<name>ID</name>
<javaClass>java.lang.String</javaClass>
</attribute>
</class>
<class>
<name>Alarm</name>
<superClass>Event</superClass>
<attribute>
<name>PerceivedSeverity</name>
<javaClass>java.lang.String</javaClass>
</attribute>
<attribute>
<name>Acknowledged</name>
<javaClass>java.lang.Boolean</javaClass>
<defaultValue>false</defaultValue>
</attribute>
</class>
</classes>
The following table describes the elements that you can use to define your business model in XML format. You can also find a description of this format in the XML schema file
model.xsd.
Elements in an XML business model
XML element | Attributes | Default | Description |
<classes> | None | | Delimits classes definition. This element is required. The file containing classes should necessarily start and end with this element. This element can be used inside data (see Elements in an XML data file ). This element contains <class> elements. |
<class> | None | | Contains a class definition. The class definition contains a name and possibly a <superClass> element and some <attribute> elements. |
<superClass> | None | | Contains the name of the superclass. |
<name> | None | | Contains the name of the class or of the attribute being defined. |
<attribute> | None | | Defines an attribute in the current <class>. The attribute contains a <name>, a <javaClass>, and optionally a <defaultValue>. |
<javaClass> | None | | Contains the name of the Java™ class of the attribute (for example java.lang.String ). |
<defaultValue> | | | Contains the default value of an attribute. |
| javaClass | The Java class of the attribute. | Sometimes the Java class of the default value is not the Java class of the attribute (for example, if the Java class of the attribute is abstract). This attribute allows you to specify the Java class of the default value. |
| null | false | If the default value is to be null, you can set this optional attribute to true. |
Inheritance
The dynamic classes created from an XML file can inherit from existing classes, in the same way as the dynamic classes that you can create using the Java API, which are either classes created from JavaBean™ classes or custom
IlpClass implementations retrieved by the static
GetIlpClass() method.
The order in which classes are defined within the element <classes> has no impact when loading classes that have inheritance relationships. In other words, you can define a class before a superclass within the same <classes> element.
Attribute types
The JViews TGO schema for defining an XML business model provides a <javaClass> element that lets you assign an abstract class or interface type to an attribute (for example java.lang.Number ) and provide a default value.
How to assign an abstract class or interface type and default value to an attribute
<attribute>
<name>number</name>
<javaClass>java.lang.Number</javaClass>
<defaultValue javaClass="java.lang.Integer">100</defaultValue>
</attribute>
You may want to specify that an attribute has a null default value. Sometimes it is difficult to distinguish between a null value and an empty value. For example, if you have an attribute of type String, its default value will be "".
How to specify a null default value for an attribute
<attribute>
<name>emptyString</name>
<javaClass>java.lang.String</javaClass>
<defaultValue />
</attribute>
Therefore, there is another XML attribute for default values to specify that the default value is null:
<attribute>
<name>nullString</name>
<javaClass>java.lang.String</javaClass>
<defaultValue null="true" />
</attribute>
Type conversion
The types assigned to attributes of dynamic classes defined in an XML file should be recognized by the XML parser in order to load data contained in these classes.
Since attribute types may be complex, JViews TGO supports both simple attribute types, which can be read from a single string, and complex attribute types which can be composed of several XML tags.
For converting simple types, the XML parser uses the type converter service of the current application context (see
Type converter). It executes the type conversion by calling the methods
createJavaInstance and
createStringValue. These methods support all the types defined in
java.lang, plus extra ones such as:
Dates (instances of
java.util.Date ). The following format is supported:
"yyyy'-'MM'-'dd'T'HH':'mm':'ss"
Colors (instances of
java.awt.Color ). Regular HTML formats are supported; for example:
"RED" or "#NNNNNN"
Fonts (instances of
java.awt.Font ). To know the formats that are supported, see the
java.awt.Font.decode method.
Enumerated values (instances of
ilog.util.IlEnum ).
You can extend the number of types supported by the default type converter by creating specific property editors or by subclassing the type converter.
Complex types
The interface
IlpSAXSerializable supports complex types. This interface lets you read an instance from a SAX
XmlReader and write it as a SAX event to a SAX
ContentHandler. To be recognized, this interface should be implemented by a class named
<className>SAXInfo ; or, if you are using the default type converter implementation (
IlpDefaultTypeConverter), you can register the value handler so that it is automatically taken into account by the XML parser, using the method
IlpDefaultTypeConverter.
setAttributeValueHandler.
Most of the
JViews TGO classes that can be used as attribute types have a corresponding
SAXInfo class. For example, the
IlpPoint class in the
ilog.cpl.graphic package comes with the
IlpPointSAXInfo class. When an
IlpPoint is to be read, the default type converter checks whether there is a corresponding
IlpSAXSerializable instance. If not, it will try to load the
IlpPointSAXInfo class. If it succeeds, this class will be returned as the
IlpSAXSerializable interface of the
IlpPoint class.
As an example, here is the code of the class IlpPointSAXInfo.
How to use the IlpSAXSerializable interface with complex types
/**
* Returns a SAX handler capable of reading the attribute.
* To avoid an instance of a SAX handler being used simultaneously
* by two concurrent threads, this method should either return a new
* instance of a SAX handler each time it is called or take advantage of
* the java.lang.ThreadLocal class to return a different
* instance for each thread.
* @return A SAX event handler.
*/
public IlpSAXAttributeValueHandler getSAXHandler() {
return new IlpSAXPointHandler();
}
public static class IlpSAXPointHandler extends IlpSAXAttributeValueHandler {
protected float x;
protected float y;
/**
* Indicates the beginning of an element.
* By default, this method only clears the content of the element.
*/
public void startElement(String namespaceURI,
String localName,
String qName,
Attributes atts) throws SAXException {
if (localName.equals(finalTag)) {
x = y = 0.0f;
}
super.startElement(namespaceURI,localName,qName,atts);
}
/**
* Notifies the end of an element.
* When this method is called for the "attribute" element,
* the <CODE>getAttributeValue</CODE> method is called, the object
* is modified accordingly, and parsing continues.
*/
public void endElement(String namespaceURI,
String localName,
String qName) throws SAXException {
if (localName.equals("x")) {
x = Float.parseFloat(getContent());
}
if (localName.equals("y")) {
y = Float.parseFloat(getContent());
}
super.endElement(namespaceURI,localName,qName);
}
/**
* Is called at the end of the "attribute" element.
*/
protected Object getAttributeValue() {
Object value = new IlpPoint(x,y);
return value;
}
}
/**
* Writes the <CODE>value</CODE> to a SAX ContentHandler.
* The method translates the object as SAX ContentHandler method calls.
* @param value The object to write.
* @param typeConverter The type converter that may be needed to translate
* values to strings.
* @param outputHandler The SAX ContentHandler used by this method.
* @see ilog.cpl.util.IlpTypeConverter#createStringValue(Object,IlpKey)
*/
public void output(Object value,
IlpTypeConverter typeConverter,
ContentHandler outputHandler)
throws SAXException {
IlpPoint point = (IlpPoint)value;
String valueStr = String.valueOf(point.x);
outputHandler.startElement("","x","x",IlpSAXSerializable.EMPTY_ATTRS);
outputHandler.characters(valueStr.toCharArray(),0,valueStr.length());
outputHandler.endElement("","x","x");
valueStr = String.valueOf(point.y);
outputHandler.startElement("","y","y",IlpSAXSerializable.EMPTY_ATTRS);
outputHandler.characters(valueStr.toCharArray(),0,valueStr.length());
outputHandler.endElement("","y","y");
}
}
Extending a predefined business class in XML
To extend a predefined business class dynamically, you can create a new instance of IlpDefaultClass from an XML description of the class.
The following example demonstrates how to create a subclass of a predefined business class in XML.
How to create a subclass of a predefined business class in XML
<class>
<name>Element</name>
<superClass>ilog.tgo.model.IltNetworkElement</superClass>
<attribute>
<name>throughput</name>
<javaClass>java.lang.Integer</javaClass>
</attribute>
</class>
The syntax is the same as for creating a regular class with XML. See
Defining the business model in XML.
The newly created class extends the
IltNetworkElement predefined business class and has an additional attribute (
throughput ).
This class is an instance of both the IlpClass Element and the Java™ class ilog.tgo.model.IltNetworkElement.
As shown in the following figure, an instance of Element derives from two class hierarchies: the dynamic class hierarchy and the Java class hierarchy.
Deriving instances from the dynamic and the Java class hierarchies
If you create an instance of the
IlpClass Element with XML, the created object will be an instance of the Java class
IltNetworkElement.
Loading the business model
Dynamic classes can be loaded either when the application starts up, that is, when
IltSystem.
Init is called, or later when data is loaded in a data source. See
Adding business objects from JavaBeans.
Loading at application start up
To load a model when the application is launched, you can modify the deployment descriptor by adding the following lines inside the <deployment> element:
<classManager>
<file>mymodel.xml</file>
</classManager>
The <classManager> element can include a number of <file> tags. The path to these files is resolved by means of the URL access service, which is created and configured by the deployment descriptor.
For more information, see
Class manager.
Loading with the data in a data source
You can insert business model XML elements, that is, complete
<classes> elements, in a data source file. For details, refer to
Adding business objects from JavaBeans.
Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.