summaryrefslogtreecommitdiff
path: root/tutorial/VerboseClass.html
blob: 43e063723230dfd26ca1706e8eced8573dc56daa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> 
<html>


<head>
<title>OpenJava : Tutorial</title>
<meta http-equiv="Keywords" content="java, openjava, reflection">
</head>


<body bgcolor="white"
        text="#000000" link="#007fff" vlink="#006fdf" alink="#ff0000">


<!---------------------------------------------------------------------->


<center>

<h1><font color="Blue">OpenJava Tutorial</font></h1>

</center>


<!---------------------------------------------------------------------->
<hr width="100%">
<!---------------------------------------------------------------------->


<h2>2. <font color="blue">Hello World</font></h2>


<p>A MOP version of "hello world" is verbose objects, which print a message
for every method call.
We choose them as our first example.

<p>The MOP programming in OpenJava is done through three steps :
<ul>
<li>(1) decide what the base-level program should look like,
<li>(2) figure out what it should be translated into and what runtime support
code is needed,
</ul>
and
<ul>
<li>(3) write a meta-level program to perform the translation and also
write the runtime support code.
</ul>
We implement the verbose objects through these steps.


<h3>2.1. What the base-level program should look like</h3>

<p>Most of example programs given in the text are ready to be executed by
the OpenJava system and are similar in form to:

<br><blockquote><pre><font color=darkblue>
public class <font color=black>Hello</font> <b>instantiates <font color=black>VerboseClass</font></b> {
    public static <font color=black>void</font> main( <font color=black>String</font>[] args ) {
        hello();
    }
    static <font color=black>void</font> hello() {
        <font color=black>System</font>.out.println( "<font color=gray><i>Hello, world.</i></font>" );
    }
}
</font></pre></blockquote>

<p>This is an ordinary source code except for the first line.
The annotation in the first line :

<br><blockquote><pre><font color=darkblue>
instantiates <font color=black>VerboseClass</font>
</font></pre></blockquote>

is a special annotation for OpenJava, and means that the semantics of
the class <b>Hello</b>, called metaobject, is specified to be extended
by the class <b>VerboseClass</b>, called metaclass.  In practice, the
source code of the class <b>Hello</b> is translated by the object of
the metaclass <b>VerboseClass</b>.


<h3>2.2. What the base-level program should be translated</h3>

<p>In this example, consider the metaclass <b>VerboseClass</b> to extend
the metaobjects to show messages for every call for its methods.  In
practice, the statement in order to put the message into system
standard output is to be inserted at the first line of each methods'
body in the class <b>Hello</b> via the metaclass <b>VerboseClass</b>.  Then
the first source code of class <b>Hello</b> should be translated into:

<br><blockquote><pre><font color=darkblue>
public class <font color=black>Hello</font> {
    public static <font color=black>void</font> main( <font color=black>String</font>[] args ) {
        <b><font color=black>System</font>.out.println( "<i>main is called.</i>" );</b>
        hello();
    }
    static <font color=black>void</font> hello() {
        <b><font color=black>System</font>.out.println( "<i>hello is called.</i>" );</b>
        <font color=black>System</font>.out.println( "<i>Hello, world.</i>" );
    }
}
</font></pre></blockquote>



<h3>2.3. Write a meta-level program</h3>

<p>Now, we write a meta-level program.  What we should do is to
translate only method member in the class <b>Hello</b> in the way
shown above.  We can easily do that if we use the MOP.

<p>In OpenJava, classes are objects as in Smalltalk.  We call them class
metaobjects when we refer to their meta-level representation.  A
unique feature of OpenJava is that a class metaobject translates the
source code defining the class at compile time.  For example, the
class metaobject for <b>Hello</b> translates a method declaration
<b>hello()</b>.

<p>By default, class metaobjects are identity functions; they do not
change the program.  So, to implement our translation, we define a new
metaclass - a new class for class metaobjects - and use it to make the
class metaobject for <b>Hello</b>.  Such a metaclass
<b>VerboseClass</b> has been compiled and is similar to in form to:

<br><blockquote><pre><font color=darkblue>
import openjava.mop.*;
import openjava.ptree.*;
public class <font color=black>VerboseClass</font> instantiates <font
color=black>Metaclass</font> extends <font color=black>OJClass</font>
{
    public <font color=black>void</font> translateDefinition() throws <font color=black>MOPException</font> {
        <font color=black>OJMethod</font>[] methods = getDeclaredMethods();
        for (<font color=black>int</font> i = 0; i < methods.length; ++i) {
            <font color=black>Statement</font> printer = makeStatement(
                "<font color=gray><i>System.out.println( \"</i></font>" + methods[i] +
                "<font color=gray><i> is called.\" );</i></font>"
            );
            methods[i].getBody().insertElementAt( printer, 0 );
        }
    }
}   
</font></pre></blockquote>

<p>Here, the metaclass <b>VerboseClass</b> is a base-level class of
OpenJava from the view point of meta programming and in fact it
declares its metaclass as <b>openjava.mop.Metaclass</b> though could
be written in the regular Java.  It inherits from
<b>openjava.mop.OJClass</b> and overrides one member function.

<p>In order to translate the definition part (callee-side) of the base
class <b>Hello</b>, we should override the method
<tt>translateMethodDeclaration()</tt>, which is to be invoked by the
system automatically.  In the method
<tt>translateMethodDeclaration()</tt>, we can obtain all the method
objects which are declared in the base-level class by invoking the
method <tt>getDeclaredMethods()</tt> on the class object
<tt>this</tt>.

The method <tt>makeStatement()</tt> is the partial parser which
produces a <b>openjava.ptree.Statement</b> object from a
<b>java.lang.String</b> object.  Here we produces a statement which
print that the method is called, then inserts it at the body for each
method.


<h3>2.4. Compile, debug, and run</h3>

<p>On a Sun workstation, the first class, stored in the file
<tt>Hello.oj</tt>, can be translated into Java source code file named
<tt>Hello.java</tt> and the generated source code can be compiled into
byte code file named <tt>Hello.class</tt> by giving the commands:

<br><blockquote><pre>
% ojc VerboseClass.oj
% ojc Hello.oj
</pre></blockquote>

<p>Execution of its bytecode on JVM (Java Virtual Machine) produces
the output :

<br><blockquote><pre><font color=darkred>
void Hello.main(String[]) is called.
void Hello.hello() is called.
Hello, world.
</font></pre></blockquote>


<!---------------------------------------------------------------------->
<hr width="100%">
<!---------------------------------------------------------------------->


<center>

Please send any message to :
<address>
mich@acm.org
</address><BR>

</center>


<font size=1>Copyright (C) 1999 by Michaki Tatsubori.</font><br>
<font size=1>Java(TM) is a trademark of Sun Microsystems, Inc.</font>


<!---------------------------------------------------------------------->


</body>


</html>