This
example uses the development of a generic Compute Sum program to
illustrate XVCL concepts and the usage of XVCL commands.
Problem
description
In a
galaxy far far away, there is a peaceful world of aliens and humans.
We
assume that know that aliens and humans have the following commonalities: they
all have name, age, weight and height. A human by default has one head, two
legs, while an alien may have more than one head and some wings. Different
aliens may have different number of heads and wings. A human also needs money
that is not necessary for the aliens.
Now we
want to compute the total number of heads of all aliens and humans in this
world. For aliens, we are also curious of the total number of wings. For humans,
we also want to know the total amount of the money they possess. So how shall we
develop a flexible and generic solution for computing the total number of
different properties of different objects? We shall now introduce an XVCL-based
solution.
We have
identified the following variants from the problem description:
· Class (CLASS): We have two
different classes here, Human and Alien.
· Computable properties of
the objects (COMPUTABLE): Could be Head, Wing, Money, Legs, etc.
· The type of the value (VALUE_TYPE):
Values of the properties could be of different types.
For example, Head is of type
integer, while Money is of type double.
· Initial sum (INIT_SUM): The
initial sum value before the computation.
Our
x-frames should be flexible and generic enough to accommodate all these
variants. From the x-frames, we could construct specific programs for computing
sum of different properties of different objects.
The Being x-frame
Since Human and Alien have much in common, we could design a generic
x-frame to capture the commonality between them. This x-frame is also capable of
accommodating variability between the two.
Figure 1
shows the Being x-frame.
<x-frame name="Being"
language="java">
<set var="BEING"
value="Being_Class"/>
<break name="BEING_PARAMETERS"/>
class <value-of
expr="?@BEING?"/> {
String Name;
int Age;
double Weight;
double Height;
<break name="BEING_BODY"/>
public String
getName() {return Name;}
public int
getAge() {return Age;}
public
double getWeight() {return Weight;}
public
double getHeight() {return Height;}
<break
name="BEING_NEW_METHODS"/>
};
</x-frame>
Figure 1: The Being x-frame
In
Figure 1, the first line in the frame <x-frame name=”BEING" language="Java">
shows that the x-frame name is Being, and the language in which the
x-frame is written is Java. The x-frame contains a generic class. We use a XVCL
variable BEING_CLASS to represent the Java class name. The <set> command is used
here to define the meta-variable BEING_CLASS with the default value of “Being”.
This value can be overwritten by specific values defined in high-level x-frames
(e.g., in SPC). The command <value-of expr="?@BEING_CLASS?"/> indicates a place
holder where the actual value of the variable can be substituted during x-frame
adaptation.
The
x-frame captures the commonality between Human and Alien class. Common
attributes (such as Name, Age, Weight and Height) and methods that manipulate
those attributes are represented as x-frame body. The x-frame also captures
variabilities. While having much in common, Human and Alien are also different –
they have different inherent properties (attributes), and have different
methods. To accommodate more attributes and methods of the Being class, we
introduce two breakpoints BEING_BODY and BEING_NEW_METHODS, respectively. The
breakpoints define slots at which specific implementations defined in the
higher-level x-frames (e.g., in SPC) can be <insert>ed during x-frame
adaptation.
As the
x-frame may need additional meta-variables, we use the command <break name="BEING_NEW_PARAMETERS"/>
to indicate a breakpoint at which the declarations of additional XVCL variables
may be inserted.
Human x-frame
Figure 2
shows the Human x-frame. A human is the same as a being except that it also has
its unique properties – one head, two legs and some money. Thus, we can develop
Human class by adapting the Being x-frame. After adapting, the Human class has
all the attributes and methods that a being has. Human specific attributes and
methods are <insert>ed into the corresponding breakpoints.
<x-frame name="Human"
language="java">
<adapt x-frame="Being.xvcl">
<insert break="BEING_PARAMETERS">
<set var="BEINGS_CLASS" value="Human"/>
</insert>
<insert break="BEING_BODY">
int Head
= 1;
int
Legs = 2;
double Money;
</insert>
</adapt>
</x-frame>
Figure 2: The Human x-frame
Alien x-frame
Figure 3
shows the Alien x-frame. An alien is the same as a being except that it also has
its unique properties – head, wings, etc. Thus, we can also develop Alien class
by adapting the Being x-frame. After adapting, the Alien class has all the
attributes and methods that a being has. All Alien specific attributes and
methods are <insert>ed into the corresponding breakpoints.
<x-frame name="Alien"
language="java">
<adapt x-frame="Being.xvcl">
<insert
break="BEING_PARAMETERS">
<set var="BEINGS_CLASS" value="Alien"/>
</insert>
<insert
break="BEING_BODY">
int
Head;
int
Wings;
</insert>
</adapt>
</x-frame>
Figure 3: The Alien x-frame
Compute Sum x-frame
Figure 4
shows an x-frame that computes the total number of properties of a set of
objects.
This
x-frame contains a generic Java function "computeSum_func" which provides a
generic solution that supports different attributes, attribute types, and
classes. For example, it can compute the sum of Alien.Head, Alien.Wing,
Human.Head, Human.Legs, or Human.MONEY. All variants identified in Problem
Description section are accommodated.
We use a
multi-value variable VALUES to represent a set of values to be computed. The
actual value of the multi-value variable is specified in SPC. The code about
constructing an actual Java vector object (the parameter needed by the
ComputeSum function) is generated through the <while> command.
<x-frame name="ComputeSum">
<set var="INIT_SUM"
value="0"/> <!--The inital value of the sum-->
<set var="VALUE_TYPE"
value="int"/> <!--The type of the value-->
<set var="CLASS"
value="class"/> <!--The class of the objects-->
<set var="COMPUTABLE"
value="computeable"/> <!--The property to be computed-->
<set var="LT"
value="<"/> <!--The XML "less than" operator-->
<set var="GT"
value=">"/> <!--The XML "greater than" operator-->
<break name="COMPUTESUM_NEWPARAMETERS"/>
import java.util.*;
public class
ComputeSum{
// A generic Compute Sum function
public
static <value-of expr="?@VALUE_TYPE?"/> computeSum_func(Vector Objects)
{
<value-of expr="?@CLASS?"/s> object;
<value-of expr="?@VALUE_TYPE?"/> sum = <value-of expr="?@INIT_SUM?"/>;
for
(int i=0; i <value-of expr="?@LT?"/> Objects.size(); i++) {
Figure 5
shows an SPC for the ComputeSum x-frame of Figure 4. We want to compute the
total number of the heads that the aliens have. The meta-variable CLASS is set
to “Alien”, COMPUTABLE is set to “Head”, and the VALUE_TYPE is set to “int”.
We have three aliens to compute, with 1, 2 and 4 heads respectively. Given the
SPC, the XVCL processor adapts the ComputeSum and Alien x-frames, and
constructs a specific program that can compute the total number of alien heads.
Figure 6
shows another SPC for the ComputeSum x-frame. This time, we are interested in
computing the total amount of the money that the humans have. The meta-variable
CLASS is now set to “Human”, COMPUTABLE is set to “Money”, the VALUE_TYPE is set
to "double”, and the INIT_SUM is set 100. Although the class, computable
properties, properties' types, and initial value are all changed, we can still
use the same ComputeSum x-frame to construct a specific program that meets our
needs.
The
complete Compute Sum example can be downloaded from
here.
You need
an XVCL processor v2.0 (beta 1), JDOM (8.0 or above) and
a JDK 1.4 (or above) to run this example. Make sure that all needed packages are
in your class path.
The command for XVCL processing is as follows:
java
xvcl.XVCL ComputeSum.S
Please
note that this example sets the XVCL DTD path to file:///xvcl.dtd.
You may change it to reflect your XVCL settings.
A java
file ComputeSum.java will be generated after the frame (x-frame) processing. You
may then compile and execute the program:
javac ComputeSum.java
java ComputeSum
You may
try to modify the ComputeSum.S to generate different versions of the ComputeSum,
and observe how the XVCL works.