JIC Language

Author: Timo Laitinen
Date: 2004-10-31

Contents

1. About this document
1.1.About the examples
2. Introduction
2.1.Structure of a JIC file
2.2.JIC elements
2.2.1.Common element type
2.2.2.Names of the XML elements are not fixed
2.2.3.Elements encapsulate construction instructions
2.2.4.Summary
2.3.JIC attributes
3. Behaviour of JIC elements
3.1.Initializing Java instances
3.2.Executing actions
3.3.Example: Initializing a java.util.Calendar
4. Anatomy of a JIC element
4.1.Element types
4.2.Namespace of JIC elements
4.3.Order of child elements
4.4.Example JIC elements
5. Variables in the action and constructor
5.1.Built-in variables
5.2.Variables for inner value elements and global instances
5.3.Consequences
5.4.Examples
5.4.1.Referring to the element instances of inner value elements
5.4.2.Referring to the element instance of the JIC element itself
5.4.3.Referring to the element instance of the parent element
5.4.4.Referring to the cdata section of the element
6. Execution of JIC elements
7. Constructors
7.1.Built-in constructors
7.2.Specifying the constructor of an element
7.3.Implicit constructor from attributes class and parameters
7.3.1.Why to use attributes class and parameters?
7.3.2.Attributes class and parameters can replace only 'new' operations
7.3.3.Attributes parameters and instance don't mix
7.4.Default constructor of the element type
7.5.cdata constructor
8. Primitives
8.1.Wrapper objects are used instead of primitives
8.2.Wrapper objects are converted to primitives when necessary
8.3.Primitive arrays
9. Using attribute class as a type constraint
9.1.Semantics of the class attribute
9.2.Why to use the class attribute with the instance attribute
9.3.Choosing the right value
10. Global instances
10.1.When does a global instance become available?
10.2.Local variables override global variables
11. Build context
12. Accessing build parameters and overridings
12.1.Overriding element instances: attribute overridable-by
12.2.Effects of overriding
12.3.Accessing parameters directly.
13. Accessing file resources from JIC files
14. JIC element types
14.1.Element type object
14.2.Element type bean
14.3.Element type block
14.4.Element type array
14.5.Element type list
14.6.Element type Map
14.7.CData element types
15. JIC attributes
15.1.type="typeIdentifier"
15.2.instance="LJE expression"
15.3.action="LJE expression"
15.4.class="full.class.name"
15.5.parameters="LJE parameter expression"
15.6.id="identifier"
15.7.overridable-by="parameterName"
16. JIC Language and XML Namespaces
17. Validating JIC files
18. Currently unsupported features
18.1.Null values
18.2.Used-defined element types

1. About this document

This document is a specification of the JIC Language. The document serves also as a tutorial for writing JIC files.

1.1.About the examples

This document has many examples demonstrating the capabilities of the JIC Language. All the examples in this document are manipulating the standard J2SE classes. The standard Java classes are used because they are probably familiar to all Java developers. Note that JIC Language is by no means limited to operating only with the standard Java API. In real-life applications, the JIC files would manipulate mostly the application classes.

2. Introduction

JIC Language is an XML vocabulary for expressing the configuration of a graph of Java objects. The language makes it possible to represent the operations needed to construct an object graph in a declarative format. The instructions written in JIC Language are processed by the JIC Engine that executes the operations and constructs the resulting graph of objects.

The XML files containing JIC Language code are called JIC files. Here is probably the simplest JIC file. When processed by the JIC Engine, it returns the String "Hello World!".

<?xml version="1.0" encoding="UTF-8"?>
<messagexmlns="http://www.jicengine.org/jic/1.0" instance="'Hello World!'"/>

2.1.Structure of a JIC file

A JIC file doesn't have any pre-specified internal structure. It is simply an XML file that contains JIC elements. Every JIC element can contain other JIC element as children. Simple file can have a single element, as shown in the previous "hello world" example. Usually there are many elements.

An XML file always has only a single root element. After the JIC Engine has processed the file, it will return the element instance (introduced later) of the root element as the graph of objects. Therefore the top-most element will usually specify some kind of a "main object".

In larger JIC files, the element type (introduced later) of the root element is typically block, because that element type can contain almost any kind of sub elements. This flexibility is needed when complex Java instance graphs are built.

2.2.JIC elements

2.2.1.Common element type

JIC Language specifies a common abstract element type called simply as a JIC element. This abstract type specifies most of the functionality. The abstract type has a number of concrete subtypes that have slightly different behaviour.

2.2.2.Names of the XML elements are not fixed

JIC Language is an extraordinary XML vocabulary in that the names of the XML elements are not fixed. The names depend on both the Java API of the application being configured and the decisions of the author of the JIC file.

Usually the XML element names identify the types of the element. There are different types of JIC elements (all subclasses of the common element type) but instead of the XML element name, JIC Language uses the attribute type for identifying the type of a JIC element.

In some situations the name of an XML element is derived from the Java API - the name may match a property in a Java class, for example. In most cases the author of the JIC file may choose the element names in the same way as a programmer chooses the variable names. If the author chooses descriptive names, the JIC code becomes very readable.

All XML elements in a JIC file are considered as JIC elements.

2.2.3.Elements encapsulate construction instructions

Each JIC element encapsulates individual construction instructions - each element can create an object and execute an operation. Usually a JIC element in a JIC file corresponds to a single Java object.

2.2.4.Summary

Here is a summary of the properties of JIC elements:

The term JIC element is used when the properties common to every kind of element are discussed. The term element type is used for referring to the individual subtypes.

2.3.JIC attributes

JIC Language specifies a set of JIC attributes that hold the details of the configuration instructions:

Name Purpose
action Specifies an operation that is executed during the processing of the element.
instance An operation yielding the Java instance that is initialized by the element.
name Specifies the name of the element.
type Specifies the element type of the element.
class Specifies the type of the Java instance constructed by the element.
parameters Specifies parameters for the constructor.
id Turns the Java instance of the element instance into a global instance that can be referred by other elements.
overridable-by Makes the element instance overridable by a build parameter.

The attributes are described more thoroughly later.

3. Behaviour of JIC elements

In a JIC file, JIC elements encapsulate individual configuration instructions. When executed, each JIC element can:

  1. initialize a Java instance.
  2. execute an action.
  3. do both of the above.

These elementary capabilities give JIC Language its strength. They make it possible to encode the configuration of even complex object graphs (Java applications) into a readable XML format.

The JIC elements are divided into two groups depending on whether they execute actions or not:

value elements elements that initialize Java instances
action elements elements that execute actions
OR
elements that both initialize Java instances and execute actions.

A JIC element becomes an action element if it has an action i.e. if the action attribute is specified. Note that this doesn't depend on the element type of the element. A JIC element of any type may or may not execute an action.

A JIC element will initialize a Java instance if it has a constructor. There are many ways for specifying the constructor of an element and some element types may provide a default constructor.

Elements in the two categories differ in the way that they cooperate with their parent elements:

  1. A value element:
    • Initializes a Java instance and hands it over to its parent element
    • The parent decides how the instance is used.
    • A value element resembles a method that returns a value.
  2. An action element:
    • Executes an operation. Doesn't return anything to its parent element.
    • An action element resembles a method whose return type is void.

NOTE: don't mix these behavioural types with element types (object, block, bean, array, etc)

3.1.Initializing Java instances

If a JIC element has a constructor , it will initialize a Java instance when executed. The Java instance that is initialized is referred to as an element instance . The initialization is considered as a process that consists of the following steps:

  1. the parameters needed to obtain the Java instance are collected first. The element may create parameters by itself or obtain them from somewhere.
  2. the Java instance is obtained:
    1. a Java class is instantiated with the new operation.
    2. an instance is obtained from a factory.
    3. etc.
  3. the methods of the instance are called.
    • E.g. the properties of the instance are set.

A JIC element typically has other JIC elements as children that perform some parts of the process. They are executed as part of the execution of the parent element. Typically the parameters are produced by inner value elements (Step 1) and the method-calling is done by inner action elements (Step 2).

The step 2 is done by the JIC element itself. It has a constructor, a simple Java operation that creates or obtains the element instance. The constructor can be set with the attribute instance, although there are other ways for this also. The value of the attribute is a simple Java operation (a Limited Java Expression (LJE) to be precise) The variables in the expression refer to the element instances produced by the inner value elements.

3.2.Executing actions

Action elements execute actions. It this context an action is a simple Java operation like a method call for example. The execution of an action may be considered to have the following steps:

  1. the necessary parameters are created (or obtained).
  2. the method is invoked.

Action elements use typically child elements for creating the parameters. The action is set with the attribute action, whose value is a Java expression. (actually a Limited Java Expression (LJE).) The variables in the expression refer to the element instances produced by the inner value elements.

Note that the return value of the action is discarded.

3.3.Example: Initializing a java.util.Calendar

Here is an example JIC file that demonstrates the initialization of a java.util.Calendar instance. A couple of the elements also execute actions:

<?xml version="1.0" encoding="UTF-8"?>
<calendarxmlns="http://www.jicengine.org/jic/1.0" instance="new java.util.GregorianCalendar(year,month,date)">
<year instance="2004"/>
<month instance="9"/>
<date instance="9"/>
<lenient action="parent.setLenient(this)" instance="true"/>
<timeZone action="parent.setTimeZone(this)" instance="java.util.TimeZone.getTimeZone(id)">
<id instance="'GMT'"/>
</timeZone>
</calendar>

In the example, the initialization process is executed as follows:

  1. the constructor parameters are obtained from child elements <year>, <month> and <date>
  2. The constructor of the <calendar> is executed with the necessary parameters and the java.util.GregorianCalendar instance is got as a result.
  3. the java.util.GregorianCalendar instance is given to the elements <lenient> and <timeZone>, which set the properties lenient and timeZone of the instance. The two elements are only ones that perform actions.

This table summarizes the properties of the elements in the example.

element constructor
(operation)
element instance action
(operation)
behavioural type
calendar new java.util.GregorianCalendar(year, month, date) instance of java.util.GregorianCalendar - value element
year 2004 instance of java.lang.Integer - value element
month 9 instance of java.lang.Integer - value element
date 9 instance of java.lang.Integer - value element
lenient true instance of java.lang.Boolean parent.setLenient(this) action element
timezone java.util.TimeZone.getTimeZone(id) instance of java.util.TimeZone parent.setTimeZone(this) action element
id 'GMT' "GMT" (a String) - value element

The example corresponds roughly to the following Java code:

int year = 2004;
int month = 9;
int date = 9;

java.util.Calendar calendar = new java.util.GregorianCalendar(year,month,date);

boolean lenient = true;
calendar.setLenient(true);

String id = "GMT";
java.uti.TimeZone timeZone = java.util.TimeZone.getTimeZone(id);
calendar.setTimeZone(timeZone);

return calendar;

When the JIC Engine processes the file, the instance of the root element is returned as the result. Because the root element is not referred by anyone, the name of the root element could be anything. It is naturally wise to choose a clear name.

4. Anatomy of a JIC element

A JIC element has the following characteristics:

  1. It always has a name
  2. It might have a constructor .
  3. It might have an action .
  4. It must have either a constructor or an action. It could have both.
  5. It might have an id .
  6. It might have inner JIC elements as children:
    1. inner value elements
      1. elements used as constructor parameters
      2. elements used as action parameters
      3. other elements. (called additional value elements)
    2. inner action elements

These properties are common to all JIC elements, regardless of the element type of the element. The following table lists these properties together with a short description.

Property Value Purpose XML implementation
name String
(Java variable name)
If the element is a value element, the parent element uses the element name for referring to the element instance of the element.

The name should be a valid Java variable name.

The name of an action element could be virtually anything. It is used mainly in error messages.
The local name of the XML element specifies the name.

The name can also be specified with JIC attribute name.
constructor Java operation Creates (or obtains) the element instance i.e. the Java instance initialized by the element. many ways:
  1. depending on the element type, the element might have a built-in constructor.
  2. if present, the attribute instance specifies the constructor.
  3. if present, the attributes class and parameters specify an implicit constructor.
  4. depending on the element type, the element might have a default constructor.
  5. if none of the above applies and the element contains cdata, the cdata-string will become element instance of the element. (a static constructor will be used that always returns the String value of the cdata.)
action Java operation A method invocation. May set the property of the element instance of the parent. Or do something else. attribute action specifies the action.
id String Makes the element instance a global instance, which can be referenced by any element. (normally only the parent element can refer to the instance). The id must be unique within the same JIC file. set with the attribute id.
inner value elements JIC element The element instances of the inner value elements can be used in many ways:
  1. as parameters for the constructor
  2. as parameters for the action
  3. other uses depend on the element type


Note: the kind elements required/allowed depends on the action, constructor and element type of the element.
Inner XML elements that don't have the action attribute.

Any non-whitespace CDATA content inside the element will form a special child element that has the name cdata.
inner action elements JIC element Typically take part in the initialization of the element instance by setting its properties or by calling some other methods of the instance.

In principle the inner action elements could do anything. Their actions don't have to be related to the initialization of the instance. They could write a debug message to System.out, for example.
Inner XML elements that have the action attribute.

The following table tries to summarize the different properties that a JIC element might have depending on its behaviour.

Value elements Action elements
property Elements that initialize a Java instance Elements that execute an action Elements that do both
name yes yes yes
element type yes yes yes
constructor yes - yes
action rarely yes yes
id maybe. - maybe.
inner value elements
(constructor parameters)
probably.
(if the constructor uses variables)
- probably.
(if the constructor uses variables)
inner value elements
(action parameters)
- probably.
(if the action uses variables)
probably.
(if the action uses variables)
additional value elements
maybe.
(depends on the element type.)
- maybe.
(depends on the element type.)
inner action elements* maybe.
(probably for initializing the element instance created by the constructor.)
probably not maybe.
(probably for initializing the element instance created by the constructor.)

* A JIC element can almost always have an inner action element. In principle, the action elements can do anything. However, they are usually used for initializing the element instance.

4.1.Element types

JIC Language specifies several element types that are all subclasses of the common abstract JIC element type. They therefore share the common characteristics The currently supported element types are: object, bean, block, array, list, map, int, double, long, float, boolean, color, font and resource.

The element type is set with the attribute type. Default is bean.

NOTE: element types are not to be confused with the behavioural categories action elements and value elements. A JIC element of any concrete type can be either an action element or a value element depending on whether it has an action or not.

Element types are described more thoroughly later.

4.2.Namespace of JIC elements

In a JIC file, the JIC elements are XML elements that belong to the JIC namespace http://www.jicengine.org/jic/1.0 and that contain JIC attributes. The JIC attributes specify the properties of the elements.

4.3.Order of child elements

It is recommended that the child elements would be put in a following order:

  1. inner value elements that are constructor parameters.
  2. additional value elements and inner action elements. (these elements can be mixed. The best order depends on the situation.)
  3. inner value elements that are action parameters.

JIC Language doesn't force this kind of order but a common scheme would make the configuration more readable.

4.4.Example JIC elements

Element <string> has a constructor that always returns the same String:

<string instance="'this is a java.lang.String'"/>

The example above corresponds roughly to Java code:

Object string = "this is a java.lang.String";

Element <string2> has a constructor that refers to the element instance of a child element:

<string2 instance="value">
<value instance="'this is also a java.lang.String'"/>
</string2>

The example above corresponds roughly to Java code:

Object value = "this is also a java.lang.String";
Object string2 = value;

Element <string3> has a constructor that refers to the cdata of the element:

<string3 instance="cdata">this is also a java.lang.String</string3>

The example above corresponds roughly to Java code:

Object cdata = "this is also a java.lang.String";
Object string3 = cdata;

Element <string4> takes advantage of the fact that an element with cdata and no other attributes will have the cdata as its value:

<string4>this is also a java.lang.String</string4>

The example above corresponds roughly to Java code:

Object string4 = "this is also a java.lang.String";

Element <log> has an action that uses two variables: this refers to the element instance of the element itself and out refers to the element instance of the child <out>:

<log action="out.println(this)" instance="'this is a message'">
<out instance="java.lang.System.out"/>
</log>

The example above corresponds roughly to Java code:

Object log = "this is a message";
Object out = java.lang.System.out;

out.println(log);

Element <locale> has a constructor that refers to the element intances of the child elements:

<locale instance="new java.util.Locale(language,country)">
<language instance="'fi'"/>
<country instance="'FI'"/>
</locale>

The example above corresponds roughly to Java code:

String language = "fi";
String country = "FI";
Object locale = new java.util.Locale(language, country);

The same example could be written by using the attributes class and parameters instead of the attribute instance:

<locale class="java.util.Locale" parameters="language,country">
<language instance="'fi'"/>
<country instance="'FI'"/>
</locale>

Element <element> has an action that refers to the element instances of the parent element and the two child elements:

<map instance="new java.util.HashMap()">
<element action="parent.put(key,value)">
<key instance="'key1'"/>
<value type="int">12345</value>
</element>
</map>

The example above corresponds roughly to Java code:

Map map = new java.util.HashMap();

Object key = "key1";
Object value = new Integer(12345);

map.put(key,value);

5. Variables in the action and constructor

Action and constructor of a JIC element are both simple Java operations like method and constructor calls. Usually multiple Java objects take part in the operations - in case of a method call, the callee and the parameters are all Java objects.

Simple value-like objects like Strings, numbers and booleans may be defined by the operations themselves. More complex objects can be used through variables that refer to Java objects defined outside the operations.

Action and constructor are both executed in a context that makes it possible to refer to the element instances of other JIC elements. A variable in action or constructor may refer to:

  1. element instances of the inner value elements.
  2. the element instance of the parent element.
  3. global instances.
  4. the element instance of the element itself. (only in action)

(Global instances are described in more detail later.)

5.1.Built-in variables

JIC Language specifies the names of a few built-in variables:

Name Refers to
parent the element instance of the parent element.
this the element instances of the element itself.
(can be used only in the action since the variable returns to the return value of the constructor).
cdata the String-value of the cdata section of the element.
buildContext An instance of org.jicengine.BuildContext

The names are reserverd- you can't have a value element that has the same name as a built-in variable.

5.2.Variables for inner value elements and global instances

Other variables than the built-in ones are interpreted as follows:

  1. If the element has an inner value element with the same name, the variable refers to the element instance of that child element.
  2. If none of the child elements match, the variable refers to a global instance with a matching id.
  3. If there isn't a matching global instance, the variable is illegal and will result in exception when executed.

5.3.Consequences

Here are a few consequences of the variable rules:

The action of an element is set with the attribute action. In these examples the constructor is set with the attribute instance, although there are other ways for doing this also.

5.4.Examples

5.4.1.Referring to the element instances of inner value elements

<?xml version="1.0" encoding="UTF-8"?>
<localexmlns="http://www.jicengine.org/jic/1.0" instance="new java.util.Locale(language,country)">
<language instance="'fi'"/>
<country instance="'FI'"/>
</locale>

NOTE: you can refer only to instances of child elements that DO NOT have an action.

5.4.2.Referring to the element instance of the JIC element itself

<?xml version="1.0" encoding="UTF-8"?>
<listxmlns="http://www.jicengine.org/jic/1.0" instance="new java.util.ArrayList()">
<e action="parent.add(this)" instance="10"/>
<e action="parent.add(this)" instance="12"/>
<e action="parent.add(this)" instance="340"/>
<e action="parent.add(this)" instance="9"/>
</list>

5.4.3.Referring to the element instance of the parent element

See example above.

5.4.4.Referring to the cdata section of the element

<?xml version="1.0" encoding="UTF-8"?>
<messagexmlns="http://www.jicengine.org/jic/1.0" instance="cdata">Hello World!</message>

6. Execution of JIC elements

After a JIC file has been parsed, the JIC elements are executed. There is only a single root element, which is executed first. The execution is recursive - the child elements are executed as part of the execution of the parent.

The elements are always executed in the same order that they appear in the JIC file.

The execution has the following steps:

  1. child elements are executed one by one, until all inner value elements needed in the constructor are processed.
  2. The constructor of the element is executed, which yields the element instance of the element.
  3. Rest of the child elements are executed, again one by one.
  4. The element instance is now fully initialized. It is made a global instance, if necessary (if the element has the id attribute).
  5. the action of the element is executed.

NOTE: the execution order above applies only if the element is not overridden.

7. Constructors

7.1.Built-in constructors

Some element types, especially the cdata elements, specify a built-in constructor. A built-in constructor can't be overridden, so the other methods available for setting the cosntructor can't be used. See details of the element types for more information.

7.2.Specifying the constructor of an element

The attribute instance is the direct way to set the constructor of an element. Any LJE operation that returns an objects is a valid value.

All cdata element types and the type array has a default constructor that can't be overridden. Using the instance attribute with these types of elements will cause an error.

7.3.Implicit constructor from attributes class and parameters

Attributes class and parameters provide an alternative for the attribute instance. The constructor defined by the two attributes is called an implicit constructor in constrast with attribute instance, which declares the constructor quite explicitly.

The use of these two attributes is best understood with examples. Here is a jic fragment where the elements <list> and <list2> are both functionally the same:

<list instance="new java.util.ArrayList()"/>
<list2 class="java.util.ArrayList"/>

The parameters attribute is needed, if there are constructor parameters:

<list instance="new java.util.ArrayList(20)"/>
<list2 class="java.util.ArrayList" parameters="20"/>

The constructor new java.util.ArrayList(20) is derived automatically from the attributes class and parameters.

7.3.1.Why to use attributes class and parameters?

The main purpose of class and parameters attributes is to make the markup more declarative. The attributes class and parameters are shortcuts - if they cause trouble, one can always rely only on the instance attribute.

7.3.2.Attributes class and parameters can replace only 'new' operations

Most of the constructors in JIC elements will probably be new operations, like new java.util.Date() for example. However, there can be other kind of constructor operations also:

These constructors must be sets with instance attribute, which can handle all of these cases.

7.3.3.Attributes parameters and instance don't mix

The attribute parameters can not be used together with the attribute instance. Specifying them both will result in exception.

7.4.Default constructor of the element type

An element type may specify a default constructor. The default constructor is used if the constructor is not specified with the instance. Note that if the class attribute is specified, the implicit constructor will be created and the default constructor won't be used.

See details of the element types.

7.5.cdata constructor

If an element doesn't have a constructor and it contains cdata, the cdata (a String) will become the value of the element. Therefore it is very simple to create String in JIC Language:

<?xml version="1.0" encoding="UTF-8"?>
<messagexmlns="http://www.jicengine.org/jic/1.0">Hello World!</message>

In these cases the element is given a simple constructor that simply refers to the value of the cdata. The above is functionally the same as this:

<?xml version="1.0" encoding="UTF-8"?>
<messagexmlns="http://www.jicengine.org/jic/1.0" instance="cdata">Hello World!</message>

Cdata constructor can only be used, if:

8. Primitives

JICE maps the primitives (int,double,boolean) automatically to the corresponding wrapper objects (Integer,Double,Boolean) and vice versa. You don't usually have to worry about primitives.

8.1.Wrapper objects are used instead of primitives

Internally, JIC Engine manipulates always objects. Java reflection API doesn't even allow a primitive to be created, a corresponding wrapper object is created instead.

Although the following elements appear to create primitives, they all actually create wrapper objects:

<int instance="12345"/>
<int2 type="int">12345</int2>
<int3 instance="new java.lang.Integer(12345)"/>
<boolean instance="true"/>
<boolean2 type="boolean">true</boolean2>

We add a class attribute to each element for highlighting the situation. (this kind of use of the class attribute is described on the next section.)

<int class="java.lang.Integer" instance="12345"/>
<int class="java.lang.Integer" type="int">12345</int>
<int class="java.lang.Integer" instance="new java.lang.Integer(12345)"/>
<boolean class="java.lang.Boolean" instance="true"/>
<boolean class="java.lang.Boolean" type="boolean">true</boolean>

NOTE: there are JIC element types named int, double, etc. but there isn't a class named "int" or "double" - you can't write class="int".

8.2.Wrapper objects are converted to primitives when necessary

Primitives have importance only when the parameter types of a method are examined when searching for a correct method. In this method search, the wrapper classes are automatically converted to primitive types when needed. A method or constructor that accepts primitives as its parameters causes therefore no problems.

Here is an example showing that the wrapper objects are converted back to primitives when needed. The constructor of the java.lang.Integer accepts an int. The element instance of the child <int2> is a java.lang.Integer, that is converted to an int automatically.

<int instance="new java.lang.Integer(int2)">
<int2 instance="new java.lang.Integer(1234)"/>
</int>

8.3.Primitive arrays

JICE handles both primitive arrays and object arrays in a similar manner. When a primitive array is populated, the array elements are converted to primitives. The following examples demonstrate this.

<?xml version="1.0" encoding="UTF-8"?>
<arrayxmlns="http://www.jicengine.org/jic/1.0" class="java.lang.Integer[]" type="array">
<e class="java.lang.Integer" type="int">1</e>
<e class="java.lang.Integer" type="int">2</e>
</array>
<?xml version="1.0" encoding="UTF-8"?>
<arrayxmlns="http://www.jicengine.org/jic/1.0" class="int[]" type="array">
<e class="java.lang.Integer" type="int">1</e>
<e class="java.lang.Integer" type="int">2</e>
</array>

9. Using attribute class as a type constraint

In the section about constructors, the attribute class was used as the basis for the implicit constructor. However, the primary purpose of the the attribute is to specify the type of the element instance.

9.1.Semantics of the class attribute

The class attribute is similar to the type of a Java variable. A Java variable can hold any object that is compatible with the type of the variable - either the class of the object matches the type of the variable or the class of the object is a subclass of the variable type.

The type has significance also when the variable is used in Java operations i.e. when a the method of the variable object is called or the variable is used as a parameter of a method call.

The same semantics applies to the class attribute. It specifies the types of the variables referring to the element instance created by the constructor.

This nature of the class attribute becomes clear only if the constructor of the element is not an implicit constructor derived from the class attribute. This happens when the constructor is set with the instance attribute or the element type specifies a built-in constructor.

As a type constraint, the class attribute has two consequences:

  1. It guarantees that the element instance created by the constructor is an instance of a certain Java class. If the constructor yields a non-compatible object, a runtime-exception will be thrown. Note that the object can of course be a subclass of the specified class.
  2. It sets the type of the variables referring to the element instance. This has effect if the element instance is used in Java operations - for example, if a method of the element instance is to be called or if the element instance is itself used as a parameter for a method call.
    • NOTE: current implementation (JICE 1.0) doesn't use the class attribute for setting the type of the variables. The actual runtime class of the element instance is used instead. However, future implementations will use the class attribute as specified.

9.2.Why to use the class attribute with the instance attribute

If an element already has the instance attribute that already specifies the constructor of the element, the class attribute becomes optional. However, there are cases where it is wise to specify also the class attribute.

The primary objective of the functionality of the class attribute is to increase the readability of the JIC code. If the constructor is a method call whose return type is not obvious, the author of the JIC file can use the class attribute for adding more type information.

Consider the difference between the two elements <label> and <label2> in this JIC fragment:

<label instance="some.application.LabelFactory.get(name)">
<name>label_1</name>
<background instance="new java.awt.Color(0,0,255)"/>
</label>
<label2 class="javax.swing.JLabel" instance="some.application.LabelFactory.get(name)">
<name>label_2</name>
<background instance="new java.awt.Color(0,0,255)"/>
</label2>

The fact that the class attribute of the element <label2> tells that we are dealing with javax.swing.JLabel makes the configuration much clearer.

9.3.Choosing the right value

The author of the JIC file has some freedom in specifying the class attributes - either the actual class of the element instance or a superclass of the actual class can be chosen.

The class attribute should be used the same as the types of Java variables are specified. In most of the cases this means that the value should match the actual class of the element instance as closely as possible or with a reasonable precision. Interfaces or superclasses can be used if suitable.

Of course, if the element has no other constructor and the implicit constructor is derived from the class attribute, the value will match the actual class completely.

Note that some element types, for example map, provides a default constructor, not a built-in constructor. If you have an element of element type map and you set the attribute class to value java.util.Map, an error will be thrown: the element doesn't use the default constructor but tries to create the implicit constructor and fails when it can't instantiate the java.util.Map interface.

10. Global instances

So far all the variables in the action and constructor have been referring to the element instances of elements that are close to the element - child elements, the parent element or the element itself.

Global instances are a sort of global variables that are visible in the whole JIC file. The only condition is that the JIC element that defined the global instances must be processed before the instance is used.

The element instance of any value element can be made global with the attribute id. Here is an example:

<?xml version="1.0" encoding="UTF-8"?>
<containerxmlns="http://www.jicengine.org/jic/1.0" type="block" instance="formattedDate">
<dateFormat class="java.text.SimpleDateFormat" parameters="pattern,locale" id="dateFormat">
<pattern>dd.MM.yyyy HH:mm:ss z</pattern>
<locale class="java.util.Locale" parameters="language,country">
<language>fi</language>
<country>FI</country>
</locale>
</dateFormat>
<date class="java.util.Date" id="timestamp"/>
<formattedDate instance="dateFormat.format(timestamp)"/>
</container>

The elemens <dateFormat> and <date> both have the id attribute. This declares that their element instances are global instances - they can be referred by other elements.

The element <formattedDate> uses both of the global instances in its instance attribute.

10.1.When does a global instance become available?

A global instance is available in elements that come after the closing tag of the element that defined the global instance.

The elements in a JIC file are processed in the sequence that they appear in the file. A global instance becomes available as soon as the instance is fully initialized - which is when the JIC element that defines the instance has been fully processed.

10.2.Local variables override global variables

If the local context of an element contains a variable with the same name than a global variable - i.e. if an element has a child element whose name equals to the id attribute of some other element - the local variable will override the global one.

In this example, the element <formattedDate> has a child element <timestamp>, and the variable timestamp in the constructor dateFormat.format(timestamp) refers to the element instance of the child. The child element overrides the global variable timestamp created by the element <date>.

<?xml version="1.0" encoding="UTF-8"?>
<containerxmlns="http://www.jicengine.org/jic/1.0" type="block" instance="formattedDate">
<dateFormat class="java.text.SimpleDateFormat" parameters="pattern,locale" id="dateFormat">
<pattern>dd.MM.yyyy HH:mm:ss z</pattern>
<locale class="java.util.Locale" parameters="language,country">
<language>fi</language>
<country>FI</country>
</locale>
</dateFormat>
<date class="java.util.Date" id="timestamp"/>
<formattedDate instance="dateFormat.format(timestamp)">
<timestamp class="java.util.Date"/>
</formattedDate>
</container>

11. Build context

The built-in variable buildContext refers to an instance of org.jicengine.BuildContext that encapsulates the information of the current build-process. The context provides access to:

At the moment, the access to the parameters is probably the only reason to use the build-context. Build parameters are introduced in the next chapter. In the future, the build-context could be enhanced to provide means to configure the build environment somehow, for example.

See the Javadocs of the class org.jicengine.BuildContext for more details.

12. Accessing build parameters and overridings

A JIC file can receive build parameters. Parameters are named Java objects that are given to the JIC engine at "runtime" - i.e. when the JIC engine processes the JIC file. Build parameters can be used in the JIC file together with the Java objects created by the JIC elements.

A build parameter can be used in two ways:

  1. The parameter can override the element instance of a JIC element. This kind of a parameter is an optional parameter and the JIC element being overridden provides the default value.
  2. The parameter can be used explicitly. This kind of parameter is an obligatory parameter, the processing of the JIC file will fails if the parameter isn't present.

12.1.Overriding element instances: attribute overridable-by

The element instance of any JIC element can be declared to be overridable by a certain parameter. This means that the element instance declared in the JIC file serves as a default value. It is used only if the parameter is not present. If the parameter exists, the parameter value will become the element instance of the element.

The attribute overridable-by declares that the element instance of that element is overridable. The value of the attribute is the name of the parameter that can override the instance.

Here is a short example of overriding. The element <message> is overridable by the parameter named message.

<?xml version="1.0" encoding="UTF-8"?>
<containerxmlns="http://www.jicengine.org/jic/1.0" action="out.println(message)">
<message overridable-by="message">Default message</message>
<out instance="java.lang.System.out"/>
</container>

12.2.Effects of overriding

If an element is overridden, the element is will not be executed normally:

For example, if the following JIC file is processed with the parameter message, the element <inner-action-element> will never be executed.

<?xml version="1.0" encoding="UTF-8"?>
<containerxmlns="http://www.jicengine.org/jic/1.0" action="out.println(message)">
<message overridable-by="message">Default message</message>
<out instance="java.lang.System.out"/>
</container>

12.3.Accessing parameters directly.

The build-context, an instance of org.jicengine.BuildContext that is accessible by the variable buildContext, provides direct access to the build-parameters through the method:

  public Object getParameter(String name) throws JICException

The method returns the value of a parameter. An exception is thrown if the parameter is not available. In a JIC file, the parameter value is used by calling the method of the build-context in a constructor of a JIC element. For example:

<paramValue class="java.lang.String" instance="buildContext.getParameter('parameter1')"/>

It is a good idea to specify the class attribute so that it is clear what kind of a parameter is expected.

13. Accessing file resources from JIC files

JIC Language provides a method for locating various file resources with paths relative to the current JIC file. The resource model in the package org.jicengine.io is used for this.

By a resource we refer to any kind of data that is read through the java.io.InputStream or java.io.Reader classes. The resource could be a file resource that is read with java.io.FileInputStream or it could be web resource that is read through a java.net.URL. See the package org.jicengine.io for more details.

The org.jicengine.io package does not need to be used if the resources are located through absolute paths or urls. But if relative paths needs to be used, the package provides nice tools for this.

The element type resource is used for locating resources relative to the current JIC file. For an example, lets say that we have the following file structure:

 dir/
  |_ subdir/
  |   |_ file2.properties
  |
  |_ example.jic
  |_ file1.properties

In the example.jic, the Java properties file file1.properties can be read with the following JIC script:

<properties class="java.util.Properties">
<load action="load(inputStream)">
<inputStream class="java.io.InputStream" instance="resource.getInputStream()">
<resource class="org.jicengine.io.Resource" type="resource">file1.properties</resource>
</inputStream>
</load>
</properties>

The example script does approximately the following:

  1. Elent <properties> creates an empty java.util.Properties instance.
  2. The element <resource> creates an instance of org.jicengine.io.Resource that points to the properties file.
  3. The element <load> obtains a java.io.InputStream instance from the <resource> element and loads the properties by calling the load method.

Of course, the other properties file is read with the same fashion. The JIC script is formulated a bit differently as an example of the options available.

<properties class="java.util.Properties">
<load action="load(this)" class="java.io.InputStream" instance="resource.getInputStream()">
<resource class="org.jicengine.io.Resource" type="resource">subdir/file2.properties</resource>
</load>
</properties>

The org.jicengine.io package is a good tool for reading resources. If you want to only resolve the url to the resource instead of reading it, most, but not all, of the implementations of the org.jicengine.io.Resource interface support also this.

14. JIC element types

Element types can be thought of as concrete implementations of the abstract JIC element type. The general type already specifies most of the aspects of JIC elements, so the subclasses differ from each other only in a few things.

The attribute type specifies the element type of a JIC element. Default type is bean. Most of the types are identified only by their name. However, some element types can also be parametrized. Currently only the type constant-of uses a parameter.

Currently, an element type specifies:

All other aspects are common to all JIC elements

Most of the element types exist only because they make the XML code nicer or more compact. Only a few of the types are obligatory - without them, JIC Language couldn't initialize any kind of Java object.

Here is a simple example of an element type. The type int makes it easier to specify an integer in the cdata section because it provides a default constructor that parses the cdata string into an integer.

<value instance="java.lang.Integer.parseInt(cdata)">123</value>
<value type="int">123</value>

The types can be categorized as follows:

The element types are described one by one in the following chapters.

14.1.Element type object

Purpose A simple type that doesn't add any additional features to the common JIC element features. However, there's probably no reason to use the object type instead of the default element type bean.
Additional value elements Doesn't allow any additional value elements. All inner value elements must be used in action or constructor of the element. An error will be thrown if an additional value element is encountered.
cdata May contain cdata, if the variable cdata is used in the action or constructor.
Default / built-in constructor

No.

14.2.Element type bean

Purpose Makes it easier to set properties. Many Java classes have bean-like properties that are set when the object is initialized.
Additional value elements All additional value elements are used for setting the properties of the element instance. See example below.
cdata May contain cdata. If the cdata is not used in the action or constructor, it will be used for setting a property named cdata. Since most Java classes won't probably have a method setCdata(String), this may result in confusing error messages.
Default / built-in constructor

No.

Here is an example how the two properties lenient and timeZone of the java.util.Calendar would be set with the element type object:

<?xml version="1.0" encoding="UTF-8"?>
<calendarxmlns="http://www.jicengine.org/jic/1.0" type="object" instance="new java.util.GregorianCalendar()">
<lenient action="setLenient(this)" instance="true"/>
<timeZone action="setTimeZone(this)" instance="java.util.TimeZone.getTimeZone(id)">
<id instance="'GMT'"/>
</timeZone>
</calendar>

With element type bean, the two action attributes can be removed and the configuration becomes a bit simpler:

<?xml version="1.0" encoding="UTF-8"?>
<calendarxmlns="http://www.jicengine.org/jic/1.0" instance="new java.util.GregorianCalendar()">
<lenient instance="true"/>
<timeZone instance="java.util.TimeZone.getTimeZone(id)">
<id instance="'GMT'"/>
</timeZone>
</calendar>

The action attributes are removed from the <lenient> and <timeZone> elements. This turns the two elements into additional value elements. The <calendar> element will now call the setLenient() and setTimeZone methods by itself.

14.3.Element type block

Purpose When a large Java instance graph is constructed, the Java instances form often a real graph instead of a tree. Type block makes it possible to break the XML tree structure and assemble a graph by using global instances. Type block is often used as the type of the root-element.
Additional value elements All additional value elements are allowed. Nothing special is done with them, they are just allowed to exist.
cdata May contain cdata.
Default / built-in constructor

No.

block makes it possible to put any number of JIC elements inside a single JIC element. Here is an example where the top-level element has the element type block:

<?xml version="1.0" encoding="UTF-8"?>
<containerxmlns="http://www.jicengine.org/jic/1.0" type="block" instance="dates">
<dateFormat class="java.text.SimpleDateFormat" parameters="pattern" id="parseFormat">
<pattern>yyyy-MM-dd HH:mm:ss</pattern>
</dateFormat>
<dates instance="new java.util.ArrayList()">
<date action="parent.add(this)" instance="parseFormat.parse(cdata)">2004-01-01 15:00:00</date>
<date action="parent.add(this)" instance="parseFormat.parse(cdata)">2004-02-01 15:00:00</date>
<date action="parent.add(this)" instance="parseFormat.parse(cdata)">2004-03-01 15:00:00</date>
</dates>
</container>

The <dateFormat> element is used in the three <date> elements. Element type block make it possible to declare first the <dateFormat> as a global instance and then use it in the other elements.

If the element type of the <container> would be set to bean, the previous would not be possible. In that case the <dateFormat> and the <dates> elements would be used for setting properties dateFormat and dates.

14.4.Element type array

Purpose Makes it possible to create both object arrays and primitive arrays.
Additional value elements All additional value elements are used as array elements. The names of the elements have no meaning.
cdata Can't contain cdata.
Default / built-in constructor

Has a custom built-in constructor that will instantiate and populate an array. The constructor can't be expressed as a value of the instance attribute.

Here are a few examples:

<?xml version="1.0" encoding="UTF-8"?>
<arrayxmlns="http://www.jicengine.org/jic/1.0" class="int[]" type="array">
<e instance="1"/>
<e instance="2"/>
<e instance="3"/>
<e instance="4"/>
</array>
<?xml version="1.0" encoding="UTF-8"?>
<arrayxmlns="http://www.jicengine.org/jic/1.0" class="java.lang.String[]" type="array">
<e>Element 1</e>
<e>Element 2</e>
<e>Element 3</e>
<e>Element 4</e>
</array>

14.5.Element type list

Purpose Makes it easier to create and populate a java.util.List instance. For convenience only, a List could be populated also manually.
Additional value elements All additional value elements are used as list elements.
cdata Can't contain cdata.
Default / built-in constructor Provides a default constructor:
instance="new java.util.ArrayList()"

Without the list type, all the elements would have to be added to the list explicitly:

<?xml version="1.0" encoding="UTF-8"?>
<listxmlns="http://www.jicengine.org/jic/1.0" instance="new java.util.ArrayList()">
<e action="parent.add(this)" instance="1"/>
<e action="parent.add(this)" instance="2"/>
<e action="parent.add(this)" instance="3"/>
<e action="parent.add(this)" instance="4"/>
</list>

With list type, the action attributes can be left out:

<?xml version="1.0" encoding="UTF-8"?>
<listxmlns="http://www.jicengine.org/jic/1.0" class="java.util.ArrayList" type="list">
<e instance="1"/>
<e instance="2"/>
<e instance="3"/>
<e instance="4"/>
</list>

14.6.Element type Map

Purpose Makes it easier to create and populate a java.util.Map instance. For convenience only, a Map could be populated also manually.
Additional value elements All additional value elements are interpreted as entries in the Map. The name of the element is used as the key and the element instance as the value.
cdata Can't contain cdata.
Default / built-in constructor Provides a default constructor:
new java.util.HashMap()

Here is an example of how to create a Map manually:

<?xml version="1.0" encoding="UTF-8"?>
<mapxmlns="http://www.jicengine.org/jic/1.0" instance="new java.util.HashMap(initialSize)">
<initialSize instance="2"/>
<element action="parent.put(key,value)">
<key instance="'key1'"/>
<value instance="'value1'"/>
</element>
<element action="parent.put(key,value)">
<key instance="'key2'"/>
<value instance="'value2'"/>
</element>
</map>

Here is the configuration of a same Map when the element type map is used:

<?xml version="1.0" encoding="UTF-8"?>
<mapxmlns="http://www.jicengine.org/jic/1.0" type="map" instance="new java.util.HashMap(initialSize)">
<initialSize instance="2"/>
<key1 instance="'value1'"/>
<key2 instance="'value2'"/>
</map>

NOTE: Only a Map whose keys are Strings can be created. If other type of keys are required, one must create the Map manually.

14.7.CData element types

CData element types are used for parsing cdata sections into Java objects. They all provide a built-in constructor which can't be overridden. Child elements will not be allowed.

The table below summarizes the built-in constructors and accepted cdata content of the element types.

Element type Element instance type Built-in constructor and accepted cdata
int java.lang.Integer

java.lang.Integer.parseInt(cdata)

Accepts integer values

<value type="int">123</value>
<value type="int">0</value>
double java.lang.Double

java.lang.Double.parseDouble(cdata)

Accepts double values

<value type="double">12.0</value>
<value type="double">0.0</value>
float java.lang.Float

java.lang.Float.parseFloat(cdata)

Accepts float values

<value type="float">12.1234</value>
<value type="float">-1234.0</value>
long java.lang.Long

java.lang.Long.parseLong(cdata)

Accepts long values

<value type="double">123</value>
<value type="double">12345678L</value>
boolean java.lang.Boolean

java.lang.Boolean.valueOf(cdata)

Accepts boolean values

<value type="boolean">true</value>
<value type="double">false</value>
constant-of/1 depends on the constant

[constructor internal to JICE]

For retrieving the value of a static field a.ka. a constant.

The type takes the name of the class owning the static field as a parameter. The name of the static field is placed in the cdata section.

This element type is for convenience only. Here are a few examples of how to refer to the values of static fields:

<out instance="java.lang.System.out"/>
<out type="constant-of(java.lang.System)">out</out>
<out instance="java.awt.FlowLayout.CENTER"/>
<out type="constant-of(java.awt.FlowLayout)">CENTER</out>
font java.awt.Font

java.awt.Font.decode(cdata)

Format is specified by java.awt.Font.decode()

<font type="font">Arial-bold-12</font>
<font type="font">Helvetica-10</font>
<font type="font">Times-italic-24</font>
color java.awt.Color

[constructor internal to JICE]

Accepts RGB or RGBA color values. Color channel values can be specified both as numbers between 0-255 or hex numbers 0-F.

<color type="color">255,127,0</color>
<color type="color">255,127,0,255</color>
<color type="color">FF9900</color>
<color type="color">FF9900FF</color>
resource org.jicengine.io.Resource

[constructor internal to JICE]

Accepts a file path that is relative to the current JIC file. The format is specified by org.jicengine.io.Resource.getResource(String)

<file type="resource">config/app.properties</file>
<image type="resource">../images/flower.gif</image>

15. JIC attributes

Attribute Purpose
type="typeIdentifier" Sets the JIC element type of the element.
action="LJE expression" Sets the action of the element.
instance="LJE expression" Sets the constructor of the element.
name="name" Sets the name of the element.
class="full.class.name" Sets the class of the element instance of the element.
parameters="LJE parameter expression" Specifies parameters for the constructor derived from the class attribute.
id="id" Makes the element instance a global instance
overridable-by="parameterName" Makes the element instance overridable by an external parameter.

15.1.type="typeIdentifier"

Effect Sets the JIC element type of the element.
Optionality Optional
Value

type="typeName", where the typeName is one of the following type names:
object, bean, block, array, list, map, int, double, long, float, boolean, color, font, resource

OR:

type="typeName(parameters)", where the typeName matches an available element type and the parameters is a comma-separated list of parameters that the type supports.

E.g. type="block()"
type="constant-of(full.class.Name)"

Default value bean

15.2.instance="LJE expression"

Effect Sets the constructor of the element - an operation that creates the element instance.
Optionality Optional. An element might not have an element instance and therefore no constructor either.
NOTE: The constructor of an element can also be specified with the class attribute.
Value

Any LJE expression that returns a value. Probably a constructor invocation or a factory-call.

Examples:
instance="new java.net.URL('http://www.jicengine.org')"
instance="java.util.TimeZone.getTimeZone('GMT')"

LJE expressions are defined in more detail in their own specification.

Default value

Usually not. Some JIC element types specify a default constructor. Some types, especially cdata element types, specify a built-in constructor, which makes the value fixed. See details on the element types.

15.3.action="LJE expression"

Effect Sets the action of the element.
Optionality Optional. Any element might or might not have an action. Also - if there is no action attribute, an element has no action.
Value

Any LJE expression. The return value of the operation will be ignored.

Examples:
action="parent.setProperty(propertyValue)"
action="java.lang.System.setProperty('example', 'example')"

LJE expressions are defined in more detail in their own specification.

If the operation calls a method of the parent, the String parent. is added to the beginning of the action automatically if required. So instead of:

action="parent.setProperty(propertyValue)"

this is enough:

action="setProperty(propertyValue)"

Default value

No.

15.4.class="full.class.name"

Effect
  1. Type constraint - Guarantees that the element instance of the element is an instance of this class (OR an instance of some subclass of this class).
  2. Alternative way for setting the constructor of the element - if the element doesn't have the instance attribute, the constructor is derived from the class attribute. See the section on implicit constructor for more details.
Optionality Optional.
Value A full class name.

NOTE: Array types are defined with the same syntax as in Java source:
class="java.lang.Object[]", class="java.util.Date[]", etc.

NOTE: Inner classes are defined in a format that includes the $ sign. Use class="java.text.DateFormat$Field" instead of class="java.text.DateFormat.Field".
Default value

No.

15.5.parameters="LJE parameter expression"

Effect Specifies the parameters given to the implicit constructor. Always used together with the class attribute.
Optionality Optional. Always used together with the class attribute. Can't be used together with the attribute instance.
Value A comma-separated list of parameters.
Any value that could be written inside the braces in a constructor invocation is valid. For example:
parameters="variable1"
parameters="variable1, variable2"
parameters="'string', 123, true, 12.34"
Default value no default.

15.6.id="identifier"

Effect Gives a global id to the element instance and turns it into a global instance that can be referenced from other JIC elements with the id.
Optionality Optional. Can be used only if the element has an element instance.
Value An identifier that is unique within the same JIC file. In other words, there can't be two elements that have the same ids.
NOTE: the identifier should be a valid Java variable name, because this makes it possible to use the id directly in the LJE expressions.
NOTE: this identifier is not related to the element name or to the overridable-by attribute.
Default value no default.

15.7.overridable-by="parameterName"

Effect Makes it possible to override the element instance by a build parameter. See the section on build parameters and overridings for more details.
Optionality Optional. Can be used only if the element has an element instance.
Value An identifier that specifies the name of the overriding parameter.
NOTE: currently, a JIC file could contain two overridable elements with the same identifier i.e. the same build parameter would override multiple elements, if the Java classes of the elements are the same. Don't yet know whether this would be a good thing or not so try to avoid that.
Default value no default.

16. JIC Language and XML Namespaces

JIC Engine accepts only XML elements that are in the JIC namespace http://www.jicengine.org/jic/1.0. All other elements will cause an error when a JIC file is processed.

NOTE: elements in other namespaces could be allowed in the future, if there would be a reason to accept them.

Attributes that have no namespace or that are in the JIC namespace http://www.jicengine.org/jic/1.0 are interpreted as JIC attributes.

However, attributes that belong to other namespaces are silently ignored.

It is therefore possible that the elements in a JIC file have some non-JICE attributes. The rationale is that applications could add some application specific meta-data into the elements if necessary.

17. Validating JIC files

Because JIC Language doesn't specify the names of the XML elements, no functional dtd or XML Schema can be created. Valid XML content depends on the used Java API and on the decisions of the author of the file.

18. Currently unsupported features

This is a section for features which could be expected from JIC Language but which are currently not supported.

18.1.Null values

Null values are not currently supported.

That means that the element instance of a JIC element can never be null. If the constructor of an element yields null, an exception will be thrown.

It is also impossible to give null as a parameter to a method call.

18.2.Used-defined element types

Custom element types can't be defined.