Author: Timo Laitinen
Date: 2004-10-02
Contents
1. Different configuration styles
2. Procedural configuration style
3. Declarative configuration style
4. Example: Refactoring code from procedural to configuration style
4. 1. Original JIC file
4. 2. Step 1: Move values from actions
4. 3. Step 2: Remove action attributes that set properties
4. 4. Step 3: The use of variable PARENT is implicit in action attributes
4. 5. Step 4: Move values from contructors to child elements
4. 6. Step 5: Move the values into CDATA sections
4. 7. Step 6: Use attributes class and parameters instead of instance
4. 8. Step 7: String-valued CDATA elements don't need a constructor
4. 9. Step 8: Take advantage of element types
1. Different configuration styles
JIC Language makes it possible to write the configuration in more than one way. This chapter tries to describe two different styles for writing JIC code: declarative and procedural configuration styles.
Real-world configurations will probably mix both styles. However, the understanding of these two approaches makes the JIC Language easier to understand.
2. Procedural configuration style
Producedural configuration style is simpler than the declarative one. It is based on the use of attributes action
and instance
, which form a sort of core of the JIC Language. The attributes are described in more detail later.
An example of a procedural styled configuration:
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame('This is a JFrame')">
<contentPane instance="PARENT.getContentPane()">
<label action="PARENT.add(this)" instance="new javax.swing.JLabel('This is a JLabel')"/>
<opaque action="PARENT.setOpaque(true)"/>
<background action="PARENT.setBackground(this)" instance="new java.awt.Color(200,90,90)"/>
</contentPane>
<size action="PARENT.setSize(this)" instance="new java.awt.Dimension(300,300)"/>
</jframe>
The example creates a javax.swing.JFrame
with a javax.swing.JLabel
inside it. Few of the properties of the content-pane are set (background
and opaque
).
Attributes action
and instance
contain simple Java commands. It is relatively easy for a Java programmer to understand what is "happening" when the configuration is processed although he/she would have only a little knowledge of the JIC Language.
On the other hand, the configuration is more difficult to understand for a non-Java programmer. Most of the information is in Java commands, including data values (numbers, Strings and booleans). The configuration is not as structured as in the declarative style - Java expressions are not XML and are difficult to manipulate with XSLT, for example.
However, procedural configuration style is easy to learn. And it is not always important to write the configuration in a structured way.
3. Declarative configuration style
Declarative configuration style builds upon the procedural style. It is based on the semantics of the core attributes action
and instance
, but takes also advantage of other JIC Language features that make the configuration more declarative and structured.
Declarative style tries to minimize the existence of Java expressions. All of the shortcuts available in JIC Language that make the Java commands simpler are used. All actual data values such as numbers, String and booleans are put in CDATA sections.
Here is the same JFrame-example rewritten with the declarative configuration style:
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" class="javax.swing.JFrame" parameters="title">
<title>This is a JFrame</title>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" class="javax.swing.JLabel" parameters="text">
<text>This is a JLabel</text>
<opaque type="boolean">false</opaque>
</label>
<opaque type="boolean">true</opaque>
<background type="color">200,90,90</background>
</contentPane>
<size class="java.awt.Dimension" parameters="w,h">
<w type="int">300</w>
<h type="int">300</h>
</size>
</jframe>
4. Example: Refactoring code from procedural to configuration style
This chapter shows step-by-step the operations needed for refactoring the procedural-style version of the JFrame example above into the declarative-style version.
This example also demonstrates the different features of JICE.
4. 1. Original JIC file
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame('This is a JFrame')">
<contentPane instance="PARENT.getContentPane()">
<label action="PARENT.add(this)" instance="new javax.swing.JLabel('This is a JLabel')"/>
<opaque action="PARENT.setOpaque(true)"/>
<background action="PARENT.setBackground(this)" instance="new java.awt.Color(200,90,90)"/>
</contentPane>
<size action="PARENT.setSize(this)" instance="new java.awt.Dimension(300,300)"/>
</jframe>
4. 2. Step 1: Move values from actions
First we normalize the action
attributes by replacing all data values with variables.
This change applies only to the element <opaque>
.
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame('This is a JFrame')">
<contentPane instance="PARENT.getContentPane()">
<label action="PARENT.add(this)" instance="new javax.swing.JLabel('This is a JLabel')"/>
<opaque action="PARENT.setOpaque(this)" instance="true"/>
<background action="PARENT.setBackground(this)" instance="new java.awt.Color(200,90,90)"/>
</contentPane>
<size action="PARENT.setSize(this)" instance="new java.awt.Dimension(300,300)"/>
</jframe>
4. 3. Step 2: Remove action
attributes that set properties
The element type bean
is the default element type. It uses all additional inner value elements for setting properties. We can therefore remove all action
attributes that only set the properties of their parent i.e. attributes of form PARENT.setXXXX(this)
, where XXXX
equals to the name of the element. This applies to the action
attributes of elements:
-
<opaque>
-
<background>
-
<size>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame('This is a JFrame')">
<contentPane instance="PARENT.getContentPane()">
<label action="PARENT.add(this)" instance="new javax.swing.JLabel('This is a JLabel')"/>
<opaque instance="true"/>
<background instance="new java.awt.Color(200,90,90)"/>
</contentPane>
<size instance="new java.awt.Dimension(300,300)"/>
</jframe>
4. 4. Step 3: The use of variable PARENT
is implicit in action
attributes
We can remove the variable PARENT
from the action
attributes, because a method call in the action
will always point to the PARENT
by default. This applies to the elements:
-
<label>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame('This is a JFrame')">
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" instance="new javax.swing.JLabel('This is a JLabel')"/>
<opaque instance="true"/>
<background instance="new java.awt.Color(200,90,90)"/>
</contentPane>
<size instance="new java.awt.Dimension(300,300)"/>
</jframe>
NOTE: we can't remove the PARENT
from the constructor of the element <contentPane>
.
4. 5. Step 4: Move values from contructors to child elements
After handling the actions, we can refactor the constructors next.
Replace the values in the Java expressions with variables that point to child elements. This way the values are given a name and it becomes more clear what the values mean. For example, now we know that the text given to the constructor of JFrame
specifies the title.
This change applies to constructors of elements:
-
<jframe>
-
<label>
-
<background>
-
<size>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame(title)">
<title instance="'This is a JFrame'"/>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" instance="new javax.swing.JLabel(text)">
<text instance="'This is a JLabel'"/>
</label>
<opaque instance="true"/>
<background instance="new java.awt.Color(red,green,blue)">
<red instance="200"/>
<green instance="90"/>
<blue instance="90"/>
</background>
</contentPane>
<size instance="new java.awt.Dimension(width, height)">
<width instance="300"/>
<height instance="300"/>
</size>
</jframe>
4. 6. Step 5: Move the values into CDATA sections
Move all the actual data values from constructors to CDATA sections:
- If the data value is a String, this is easy - the new constructor will consist only of a single variable
CDATA
that refers to the CDATA value of the element. - If the data value is not a String, a new constructor must be defined that converts the CDATA value (String) into the required data value.
This change applies to the elements:
-
<text>
-
<opaque>
-
<red>
-
<green>
-
<blue>
-
<width>
-
<height>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" instance="new javax.swing.JFrame(title)">
<title instance="CDATA">This is a JFrame</title>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" instance="new javax.swing.JLabel(text)">
<text instance="CDATA">This is a JLabel</text>
</label>
<opaque instance="java.lang.Boolean.valueOf(CDATA)">true</opaque>
<background instance="new java.awt.Color(red,green,blue)">
<red instance="java.lang.Integer.valueOf(CDATA)">200</red>
<green instance="java.lang.Integer.valueOf(CDATA)">90</green>
<blue instance="java.lang.Integer.valueOf(CDATA)">90</blue>
</background>
</contentPane>
<size instance="new java.awt.Dimension(width, height)">
<width instance="java.lang.Integer.valueOf(CDATA)">300</width>
<height instance="java.lang.Integer.valueOf(CDATA)">300</height>
</size>
</jframe>
4. 7. Step 6: Use attributes class
and parameters
instead of instance
All constructors that are new
operations can be written with attributes class
and parameters
instead of attribute instance
. This applies to the elements:
-
<jframe>
-
<label>
-
<size>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" class="javax.swing.JFrame" parameters="title">
<title instance="CDATA">This is a JFrame</title>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" class="javax.swing.JLabel" parameters="text">
<text instance="CDATA">This is a JLabel</text>
</label>
<opaque instance="java.lang.Boolean.valueOf(CDATA)">true</opaque>
<background instance="new java.awt.Color(red,green,blue)">
<red instance="java.lang.Integer.valueOf(CDATA)">200</red>
<green instance="java.lang.Integer.valueOf(CDATA)">90</green>
<blue instance="java.lang.Integer.valueOf(CDATA)">90</blue>
</background>
</contentPane>
<size class="java.awt.Dimension" parameters="width,height">
<width instance="java.lang.Integer.valueOf(CDATA)">300</width>
<height instance="java.lang.Integer.valueOf(CDATA)">300</height>
</size>
</jframe>
4. 8. Step 7: String-valued CDATA elements don't need a constructor
A String-valued element that has CDATA don't need an explicit constructor, so we can remove all instance="CDATA"
constructors. This applies to the elements:
-
<title>
-
<text>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" class="javax.swing.JFrame" parameters="title">
<title>This is a JFrame</title>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" class="javax.swing.JLabel" parameters="text">
<text>This is a JLabel</text>
</label>
<opaque instance="java.lang.Boolean.valueOf(CDATA)">true</opaque>
<background instance="new java.awt.Color(red,green,blue)">
<red instance="java.lang.Integer.valueOf(CDATA)">200</red>
<green instance="java.lang.Integer.valueOf(CDATA)">90</green>
<blue instance="java.lang.Integer.valueOf(CDATA)">90</blue>
</background>
</contentPane>
<size class="java.awt.Dimension" parameters="width,height">
<width instance="java.lang.Integer.valueOf(CDATA)">300</width>
<height instance="java.lang.Integer.valueOf(CDATA)">300</height>
</size>
</jframe>
4. 9. Step 8: Take advantage of element types
First, we use the element types int
and boolean
for removing the quite long instance
attributes. This applies to the elements:
-
<opaque>
-
<red>
-
<green>
-
<blue>
-
<width>
-
<height>
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" class="javax.swing.JFrame" parameters="title">
<title>This is a JFrame</title>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" class="javax.swing.JLabel" parameters="text">
<text>This is a JLabel</text>
</label>
<opaque type="boolean">true</opaque>
<background instance="new java.awt.Color(r,g,b)">
<red type="int">200</red>
<green type="int">90</green>
<blue type="int">90</blue>
</background>
</contentPane>
<size class="java.awt.Dimension" parameters="width,height">
<width type="int">300</width>
<height type="int">300</height>
</size>
</jframe>
Next, we use the element type color
for making the creation of the <color>
more shorter. (the declativity of the examples decreases as a result, though..)
<jframe xmlns="http://www.jicengine.org/jic/1.0" action="this.show()" class="javax.swing.JFrame" parameters="title">
<title>This is a JFrame</title>
<contentPane instance="PARENT.getContentPane()">
<label action="add(this)" class="javax.swing.JLabel" parameters="text">
<text>This is a JLabel</text>
</label>
<opaque type="boolean">true</opaque>
<background type="color">200,90,90</background>
</contentPane>
<size class="java.awt.Dimension" parameters="width,height">
<width type="int">300</width>
<height type="int">300</height>
</size>
</jframe>