~rdoering/ubuntu/karmic/erlang/fix-535090

« back to all changes in this revision

Viewing changes to lib/orber/doc/src/ch_idl_to_erlang_mapping.xml

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-02-15 16:42:52 UTC
  • mfrom: (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090215164252-q5x4rcf8a5pbesb1
Tags: 1:12.b.5-dfsg-2
Upload to unstable after lenny is released.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="latin1" ?>
 
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
 
3
 
 
4
<chapter>
 
5
  <header>
 
6
    <copyright>
 
7
      <year>1997</year>
 
8
      <year>2008</year>
 
9
      <holder>Ericsson AB, All Rights Reserved</holder>
 
10
    </copyright>
 
11
    <legalnotice>
 
12
  The contents of this file are subject to the Erlang Public License,
 
13
  Version 1.1, (the "License"); you may not use this file except in
 
14
  compliance with the License. You should have received a copy of the
 
15
  Erlang Public License along with this software. If not, it can be
 
16
  retrieved online at http://www.erlang.org/.
 
17
 
 
18
  Software distributed under the License is distributed on an "AS IS"
 
19
  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
20
  the License for the specific language governing rights and limitations
 
21
  under the License.
 
22
 
 
23
  The Initial Developer of the Original Code is Ericsson AB.
 
24
    </legalnotice>
 
25
 
 
26
    <title>OMG IDL to Erlang Mapping</title>
 
27
    <prepared></prepared>
 
28
    <docno></docno>
 
29
    <date>1998-10-10</date>
 
30
    <rev></rev>
 
31
  </header>
 
32
 
 
33
  <section>
 
34
    <title>OMG IDL to Erlang Mapping - Overview</title>
 
35
    <p>The purpose of OMG IDL, <em>Interface Definition Language</em>, mapping
 
36
      is to act as translator between platforms and languages. An IDL 
 
37
      specification is supposed to describe data types, object types etc.</p>
 
38
    <p>CORBA is independent of the programming language used to construct
 
39
      clients or implementations. In order to use the ORB, it is
 
40
      necessary for programmers to know how to access ORB functionality 
 
41
      from their programming languages. It translates different IDL constructs
 
42
      to  a specific programming language. This chapter 
 
43
      describes the mapping of OMG IDL constructs to the Erlang programming
 
44
      language.</p>
 
45
  </section>
 
46
 
 
47
  <section>
 
48
    <title>OMG IDL Mapping Elements</title>
 
49
    <p>A complete language mapping will allow the programmer to have
 
50
      access to all ORB functionality in a way that is convenient for
 
51
      a specified programming language. 
 
52
      </p>
 
53
    <p>All mapping must define the following elements: 
 
54
      </p>
 
55
    <list type="bulleted">
 
56
      <item>All OMG IDL basic and constructed types</item>
 
57
      <item>References to constants defined in OMG IDL</item>
 
58
      <item>References to objects defined in OMG IDL</item>
 
59
      <item>Invocations of operations, including passing of
 
60
       parameters and receiving of results</item>
 
61
      <item>Exceptions, including what happens when an operation
 
62
       raises an exception and how the exception parameters are
 
63
       accessed</item>
 
64
      <item>Access to attributes</item>
 
65
      <item>Signatures for operations defined by the ORB, such as
 
66
       dynamic invocation interface, the object adapters etc.</item>
 
67
      <item>Scopes;
 
68
       OMG IDL has several levels of scopes, which are mapped to Erlang's 
 
69
       two scopes.</item>
 
70
    </list>
 
71
  </section>
 
72
 
 
73
  <section>
 
74
    <title>Getting Started</title>
 
75
    <p>To begin with, we should decide which type of objects (i.e. servers) we
 
76
      need and if two, or more, should export the same functionality. Let us
 
77
      assume that we want to create a system for DB (database) access for different
 
78
      kind of users. For example, anyone with a valid password may extract 
 
79
      data, but only a few may update the DB. Usually, an application
 
80
      is defined within a <c>module</c>, and all global datatypes are defined
 
81
      on the top-level. To begin with we create a module and the interfaces we
 
82
      need:</p>
 
83
    <code type="none">
 
84
// DB IDL
 
85
#ifndef _DB_IDL_
 
86
#define _DB_IDL_
 
87
// A module is simply a container
 
88
module DB {
 
89
 
 
90
  // An interface maps to a CORBA::Object.
 
91
  interface CommonUser {
 
92
 
 
93
  };
 
94
 
 
95
  // Inherit the Consumer interface
 
96
  interface Administrator : CommonUser {
 
97
 
 
98
  };
 
99
 
 
100
  interface Access {
 
101
 
 
102
  };
 
103
 
 
104
};
 
105
#endif    </code>
 
106
    <p>Since the <c>Administrator</c> should be able to do the same things as the
 
107
      <c>CommonUser</c>, the previous inherits from the latter. The <c>Access</c>
 
108
      interface will grant access to the DB.
 
109
      Now we are ready to define the functionality and data types we need. But, this
 
110
      requires that we know a little bit more about the OMG IDL.</p>
 
111
    <note>
 
112
      <p>The OMG defines a set of reserved case insensitive key-words, which may
 
113
        <em>NOT</em> be used as identifiers (e.g. module name). For more
 
114
        information, see
 
115
        <seealso marker="#key_words">Reserved Compiler Names and Keywords</seealso></p>
 
116
    </note>
 
117
  </section>
 
118
 
 
119
  <section>
 
120
    <title>Basic OMG IDL Types</title>
 
121
    <p>The OMG IDL mapping is strongly typed and, even if you have a good knowledge
 
122
      of CORBA types, it is essential to read carefully the following mapping to
 
123
      Erlang types.</p>
 
124
    <p>The mapping of basic types is straightforward. Note that the
 
125
      OMG IDL double type is mapped to an Erlang float which does not
 
126
      support the full double value range.</p>
 
127
    <table>
 
128
      <row>
 
129
        <cell align="left" valign="middle">OMG IDL type</cell>
 
130
        <cell align="left" valign="middle">Erlang type</cell>
 
131
        <cell align="left" valign="middle">Note</cell>
 
132
      </row>
 
133
      <row>
 
134
        <cell align="left" valign="middle">float</cell>
 
135
        <cell align="left" valign="middle">Erlang float</cell>
 
136
        <cell align="left" valign="middle"></cell>
 
137
      </row>
 
138
      <row>
 
139
        <cell align="left" valign="middle">double</cell>
 
140
        <cell align="left" valign="middle">Erlang float</cell>
 
141
        <cell align="left" valign="middle">value range not supported</cell>
 
142
      </row>
 
143
      <row>
 
144
        <cell align="left" valign="middle">short</cell>
 
145
        <cell align="left" valign="middle">Erlang integer</cell>
 
146
        <cell align="left" valign="middle">-2^15 .. 2^15-1</cell>
 
147
      </row>
 
148
      <row>
 
149
        <cell align="left" valign="middle">unsigned short</cell>
 
150
        <cell align="left" valign="middle">Erlang integer</cell>
 
151
        <cell align="left" valign="middle">0 .. 2^16-1</cell>
 
152
      </row>
 
153
      <row>
 
154
        <cell align="left" valign="middle">long</cell>
 
155
        <cell align="left" valign="middle">Erlang integer</cell>
 
156
        <cell align="left" valign="middle">-2^31 .. 2^31-1</cell>
 
157
      </row>
 
158
      <row>
 
159
        <cell align="left" valign="middle">unsigned long</cell>
 
160
        <cell align="left" valign="middle">Erlang integer</cell>
 
161
        <cell align="left" valign="middle">0 .. 2^32-1</cell>
 
162
      </row>
 
163
      <row>
 
164
        <cell align="left" valign="middle">long long</cell>
 
165
        <cell align="left" valign="middle">Erlang integer</cell>
 
166
        <cell align="left" valign="middle">-2^63 .. 2^63-1</cell>
 
167
      </row>
 
168
      <row>
 
169
        <cell align="left" valign="middle">unsigned long long</cell>
 
170
        <cell align="left" valign="middle">Erlang integer</cell>
 
171
        <cell align="left" valign="middle">0 .. 2^64-1</cell>
 
172
      </row>
 
173
      <row>
 
174
        <cell align="left" valign="middle">char</cell>
 
175
        <cell align="left" valign="middle">Erlang integer</cell>
 
176
        <cell align="left" valign="middle">ISO-8859-1</cell>
 
177
      </row>
 
178
      <row>
 
179
        <cell align="left" valign="middle">wchar</cell>
 
180
        <cell align="left" valign="middle">Erlang integer</cell>
 
181
        <cell align="left" valign="middle">UTF-16 (ISO-10646-1:1993)</cell>
 
182
      </row>
 
183
      <row>
 
184
        <cell align="left" valign="middle">boolean</cell>
 
185
        <cell align="left" valign="middle">Erlang atom</cell>
 
186
        <cell align="left" valign="middle">true/false</cell>
 
187
      </row>
 
188
      <row>
 
189
        <cell align="left" valign="middle">octet</cell>
 
190
        <cell align="left" valign="middle">Erlang integer</cell>
 
191
        <cell align="left" valign="middle"></cell>
 
192
      </row>
 
193
      <row>
 
194
        <cell align="left" valign="middle">any</cell>
 
195
        <cell align="left" valign="middle">Erlang record</cell>
 
196
        <cell align="left" valign="middle">#any{typecode, value}</cell>
 
197
      </row>
 
198
      <row>
 
199
        <cell align="left" valign="middle">long double</cell>
 
200
        <cell align="left" valign="middle">Not supported</cell>
 
201
        <cell align="left" valign="middle"></cell>
 
202
      </row>
 
203
      <row>
 
204
        <cell align="left" valign="middle">Object</cell>
 
205
        <cell align="left" valign="middle">Orber object reference</cell>
 
206
        <cell align="left" valign="middle">Internal Representation</cell>
 
207
      </row>
 
208
      <row>
 
209
        <cell align="left" valign="middle">void</cell>
 
210
        <cell align="left" valign="middle">Erlang atom</cell>
 
211
        <cell align="left" valign="middle">ok</cell>
 
212
      </row>
 
213
      <tcaption>OMG IDL basic types</tcaption>
 
214
    </table>
 
215
    <p>The <c>any</c> value is written as a record with the field typecode which
 
216
      contains the <term id="Type Code"><termdef>Type Code is a full definition of a type </termdef></term>representation,
 
217
      <seealso marker="#tk_values">see also the Type Code table</seealso>,
 
218
      and the value field itself.</p>
 
219
    <p>Functions with return type <c>void</c> will return the atom <c>ok</c>.</p>
 
220
  </section>
 
221
 
 
222
  <section>
 
223
    <title>Template OMG IDL Types and Complex Declarators</title>
 
224
    <p>Constructed types all have native mappings as shown in the table
 
225
      below.</p>
 
226
    <table>
 
227
      <row>
 
228
        <cell align="left" valign="middle"><em>Type</em></cell>
 
229
        <cell align="left" valign="middle"><em>IDL code</em></cell>
 
230
        <cell align="left" valign="middle"><em>Maps to</em></cell>
 
231
        <cell align="left" valign="middle"><em>Erlang code</em></cell>
 
232
      </row>
 
233
      <row>
 
234
        <cell align="left" valign="middle"><em>string</em></cell>
 
235
        <cell align="left" valign="middle">typedef string S;        <br></br>
 
236
void op(in S a);</cell>
 
237
        <cell align="left" valign="middle">Erlang string</cell>
 
238
        <cell align="left" valign="middle">ok = op(Obj, "Hello World"),</cell>
 
239
      </row>
 
240
      <row>
 
241
        <cell align="left" valign="middle"><em>wstring</em></cell>
 
242
        <cell align="left" valign="middle">typedef wstring S;        <br></br>
 
243
void op(in S a);</cell>
 
244
        <cell align="left" valign="middle">Erlang list of Integers</cell>
 
245
        <cell align="left" valign="middle">ok = op(Obj, "Hello World"),</cell>
 
246
      </row>
 
247
      <row>
 
248
        <cell align="left" valign="middle"><em>sequence</em></cell>
 
249
        <cell align="left" valign="middle">typedef sequence &lt;long, 3&gt; S;        <br></br>
 
250
void op(in S a);</cell>
 
251
        <cell align="left" valign="middle">Erlang list</cell>
 
252
        <cell align="left" valign="middle">ok = op(Obj, [1, 2, 3]),</cell>
 
253
      </row>
 
254
      <row>
 
255
        <cell align="left" valign="middle"><em>array</em></cell>
 
256
        <cell align="left" valign="middle">typedef string S[2];        <br></br>
 
257
void op(in S a);</cell>
 
258
        <cell align="left" valign="middle">Erlang tuple</cell>
 
259
        <cell align="left" valign="middle">ok = op(Obj, {"one", "two"}),</cell>
 
260
      </row>
 
261
      <row>
 
262
        <cell align="left" valign="middle"><em>fixed</em></cell>
 
263
        <cell align="left" valign="middle">typedef fixed&lt;3,2> myFixed;        <br></br>
 
264
void op(in myFixed a);</cell>
 
265
        <cell align="left" valign="middle">Erlang tuple</cell>
 
266
        <cell align="left" valign="middle">MF = fixed:create(3, 2, 314),        <br></br>
 
267
ok = op(Obj, MF),</cell>
 
268
      </row>
 
269
      <tcaption>OMG IDL Template and Complex Declarators</tcaption>
 
270
    </table>
 
271
 
 
272
    <section>
 
273
      <title>String/WString Data Types</title>
 
274
      <p>A <c>string</c> consists of all possible 8-bit quantities except null.
 
275
        Most ORB:s uses, including Orber, the character set Latin-1 (ISO-8859-1).
 
276
        The <c>wstring</c> type is represented as a list of integers, where
 
277
        each integer represents a wide character. In this case Orber uses, as
 
278
        most other ORB:s, the UTF-16 (ISO-10646-1:1993) character set.</p>
 
279
      <p>When defining a a string or wstring they can be of limited length or
 
280
        null terminated:</p>
 
281
      <code type="none"><![CDATA[
 
282
// Null terminated
 
283
typedef string myString;
 
284
typedef wstring myWString;
 
285
// Maximum length 10 
 
286
typedef string<10> myString10;
 
287
typedef wstring<10> myWString10;
 
288
      ]]></code>
 
289
      <p>If we want to define a char/string or wchar/wstring constant, we can
 
290
        use octal (\\OOO - one, two or three octal digits), 
 
291
        hexadecimal (\\xHH - one or two hexadecimal digits) and unicode (\\uHHHH -
 
292
        one, two, three or four hexadecimal digits.) representation as well.
 
293
        For example:</p>
 
294
      <code type="none">
 
295
const string  SwedensBestSoccerTeam = "\\101" "\\x49" "\\u004B";
 
296
const wstring SwedensBestHockeyTeam = L"\\101\\x49\\u004B";
 
297
const char  aChar  = '\\u004B';  
 
298
const wchar aWchar = L'\\u004C';
 
299
      </code>
 
300
      <p>Naturally, we can use <c>"Erlang"</c>, <c>L"Rocks"</c>, <c>'A'</c>
 
301
        and <c>L'A'</c> as well.</p>
 
302
    </section>
 
303
 
 
304
    <section>
 
305
      <title>Sequence Data Type</title>
 
306
      <p>A sequence can be defined to be of a maximum length or unbounded, and may 
 
307
        contain Basic and Template types and scoped names:</p>
 
308
      <code type="none"><![CDATA[
 
309
typedef sequence <short, 1> aShortSequence;
 
310
typedef sequence <long> aLongSequence;
 
311
typedef sequence <aLongSequence> anEvenLongerSequence;
 
312
      ]]></code>
 
313
    </section>
 
314
 
 
315
    <section>
 
316
      <title>Array Data Type</title>
 
317
      <p>Arrays are multidimensional, fixed-size arrays. The indices is language
 
318
        mapping specific, which is why one should not pass them as arguments
 
319
        to another ORB.</p>
 
320
      <code type="none">
 
321
typedef long myMatrix[2][3];
 
322
      </code>
 
323
    </section>
 
324
 
 
325
    <section>
 
326
      <title>Fixed Data Type</title>
 
327
      <p>A Fixed Point literal consists of an integer part (decimal digits), 
 
328
        decimal point and a fraction part (decimal digits),
 
329
        followed by a <c>D</c> or <c>d</c>. Either the integer part or the
 
330
        fraction part may be missing; the decimal point may be missing, 
 
331
        but not d/D. The integer part must be a positive integer less than 32.
 
332
        The Fraction part must be a positive integer less than or equal to
 
333
        the Integer part.</p>
 
334
      <code type="none">
 
335
const fixed myFixed1 = 3.14D;
 
336
const fixed myFixed2 = .14D;
 
337
const fixed myFixed3 = 0.14D;
 
338
const fixed myFixed4 = 3.D;
 
339
const fixed myFixed5 = 3D;
 
340
      </code>
 
341
      <p>It is also possible to use unary (+-) and binary (+-*/) operators:</p>
 
342
      <code type="none">
 
343
const fixed myFixed6 = 3D + 0.14D;
 
344
const fixed myFixed7 = -3.14D;
 
345
      </code>
 
346
      <p>The Fixed Point examples above are, so called, <em>anonymous</em> 
 
347
        definitions. In later CORBA specifications these have been deprecated
 
348
        as function parameters or return values. Hence, we strongly recommend that
 
349
        you do not use them. Instead, you should use:</p>
 
350
      <code type="none"><![CDATA[
 
351
typedef fixed<5,3> myFixed53;
 
352
const myFixed53 myFixed53constant = 03.140d;
 
353
typedef fixed<3,2> myFixed32;
 
354
const myFixed32 myFixed32constant = 3.14d;
 
355
 
 
356
myFixed53 foo(in myFixed32 MF); // OK
 
357
void bar(in fixed<5,3> MF); // Illegal
 
358
      ]]></code>
 
359
    </section>
 
360
    <p>For more information, see <seealso marker="fixed">Fixed</seealso> in 
 
361
      Orber's Reference Manual.</p>
 
362
    <p>Now we continue to work on our IDL specification. To begin with, we want
 
363
      to limit the size of the logon parameters (Id and password). Since the
 
364
      <c>UserID</c> and <c>Password</c> paremeters, only will be used when
 
365
      invoking operations on the <c>Access</c> interface, we may choose to define
 
366
      them within the scope that interface. To keep it simple our DB will contain
 
367
      employee information. Hence, as the DB key we choose an integer
 
368
      (<c>EmployeeNo</c>).</p>
 
369
    <code type="none"><![CDATA[
 
370
// DB IDL
 
371
#ifndef _DB_IDL_
 
372
#define _DB_IDL_
 
373
module DB {
 
374
 
 
375
  typedef unsigned long EmployeeNo;
 
376
 
 
377
  interface CommonUser {
 
378
 
 
379
     any lookup(in EmployeeNo ENo);
 
380
 
 
381
  };
 
382
 
 
383
  interface Administrator : CommonUser {
 
384
 
 
385
     void delete(in EmployeeNo ENo);
 
386
 
 
387
  };
 
388
 
 
389
  interface Access {
 
390
 
 
391
      typedef string<10> UserID;
 
392
      typedef string<10> Password;
 
393
 
 
394
      CommonUser logon(in UserID ID, in Password PW);
 
395
 
 
396
  };
 
397
 
 
398
};
 
399
#endif    ]]></code>
 
400
    <p>But what should, for example, the <c>lookup</c> operation return? One option
 
401
      is to use the <c>any</c> data type. But, depending on what kind of data it
 
402
      encapsulates, this datatype can be rather expensive to use. We might find a 
 
403
      solution to our problems among the <c>Constructed</c> IDL types.</p>
 
404
  </section>
 
405
 
 
406
  <section>
 
407
    <title>Constructed OMG IDL Types</title>
 
408
    <p>Constructed types all have native mappings as shown in the table
 
409
      below.</p>
 
410
    <table>
 
411
      <row>
 
412
        <cell align="left" valign="middle"><em>Type</em></cell>
 
413
        <cell align="left" valign="middle"><em>IDL code</em></cell>
 
414
        <cell align="left" valign="middle"><em>Maps to</em></cell>
 
415
        <cell align="left" valign="middle"><em>Erlang code</em></cell>
 
416
      </row>
 
417
      <row>
 
418
        <cell align="left" valign="middle"><em>struct</em></cell>
 
419
        <cell align="left" valign="middle">struct myStruct {        <br></br>
 
420
long a;         <br></br>
 
421
short b;        <br></br>
 
422
};        <br></br>
 
423
void op(in myStruct a);</cell>
 
424
        <cell align="left" valign="middle">Erlang record</cell>
 
425
        <cell align="left" valign="middle">ok = op(Obj, #'myStruct'{a=300, b=127}),</cell>
 
426
      </row>
 
427
      <row>
 
428
        <cell align="left" valign="middle"><em>union</em></cell>
 
429
        <cell align="left" valign="middle">union myUnion switch(long) {        <br></br>
 
430
case 1: long a;        <br></br>
 
431
};        <br></br>
 
432
void op(in myUnion a);</cell>
 
433
        <cell align="left" valign="middle">Erlang record</cell>
 
434
        <cell align="left" valign="middle">ok = op(Obj, #'myUnion'{label=1, value=66}),</cell>
 
435
      </row>
 
436
      <row>
 
437
        <cell align="left" valign="middle"><em>enum</em></cell>
 
438
        <cell align="left" valign="middle">enum myEnum {one, two};        <br></br>
 
439
void op(in myEnum a);</cell>
 
440
        <cell align="left" valign="middle">Erlang atom</cell>
 
441
        <cell align="left" valign="middle">ok = op(Obj, one),</cell>
 
442
      </row>
 
443
      <tcaption>OMG IDL constructed types</tcaption>
 
444
    </table>
 
445
 
 
446
    <section>
 
447
      <title>Struct Data Type</title>
 
448
      <p>A <c>struct</c> may have Basic, Template, Scoped Names and Constructed 
 
449
        types as members.</p>
 
450
    </section>
 
451
 
 
452
    <section>
 
453
      <title>Enum Data Type</title>
 
454
      <p>The maximum number of identifiers which may defined in an enumeration
 
455
        is 2&sup3;&sup2;. The order in which the identifiers are named in the
 
456
        specification of an enumeration defines the relative order of the
 
457
        identifiers.</p>
 
458
    </section>
 
459
 
 
460
    <section>
 
461
      <title>Union Data Type</title>
 
462
      <p>A <c>union</c> may consist of:</p>
 
463
      <list type="bulleted">
 
464
        <item>Identifier</item>
 
465
        <item>Switch - may be an integer, char, boolean, enum or scoped name.</item>
 
466
        <item>Body - with or without a <c>default</c> case; may appear at 
 
467
         most once.</item>
 
468
      </list>
 
469
      <p>A case label must match the defined type of the discriminator, and may only
 
470
        contain a default case if the values given in the non-default labels do
 
471
        not cover the entire range of the union's discriminant type. For example:</p>
 
472
      <code type="none">
 
473
// Illegal default; all cases covered by 
 
474
// non-default cases.
 
475
union BooleanUnion switch(boolean) {
 
476
  case TRUE:  long TrueValue;
 
477
  case FALSE: long FalseValue;
 
478
  default: long DefaultValue; 
 
479
};
 
480
// OK
 
481
union BooleanUnion2 switch(boolean) {
 
482
  case TRUE:  long TrueValue;
 
483
  default: long DefaultValue; 
 
484
};
 
485
      </code>
 
486
      <p>It is not necessary to list all possible values of the union discriminator
 
487
        in the body. Hence, the value of a union is the value of the discriminator
 
488
        and, in given order, one of the following:</p>
 
489
      <list type="ordered">
 
490
        <item>If the discriminator match a label, explicitly listed in a 
 
491
         case statement, the value must be of the same type.</item>
 
492
        <item>If the union contains a default label, the value must match the
 
493
         type of the default label.</item>
 
494
        <item>No value. Orber then inserts the Erlang atom <c>undefined</c>
 
495
         in the value field when receiving a union from an external 
 
496
         ORB.</item>
 
497
      </list>
 
498
      <p>The above can be summed up to:</p>
 
499
      <code type="none">
 
500
// If the discriminator equals 1 or 2 the value 
 
501
// is a long. Otherwise, the atom undefined.
 
502
union LongUnion switch(long) {
 
503
  case 1:
 
504
  case 2:  long TrueValue;
 
505
};
 
506
// If the discriminator equals 1 or 2 the value 
 
507
// is a long. Otherwise, a boolean.
 
508
union LongUnion2 switch(long) {
 
509
  case 1:
 
510
  case 2:  long TrueValue;
 
511
  default: boolean DefaultValue; 
 
512
};
 
513
      </code>
 
514
    </section>
 
515
    <warning>
 
516
      <p>Every field in, for example, a struct must be initiated. Otherwise
 
517
        it will be set to the atom <c>undefined</c>, which Orber cannot
 
518
        encode when communicating via IIOP. In the example above, invoking
 
519
        the opertion with #'myStruct'{a=300} will fail (equal to 
 
520
        #'myStruct'{a=300, b=undefined})</p>
 
521
    </warning>
 
522
    <p>Now we can continue to work on our IDL specification. To begin with, we should
 
523
      determine the return value of the <c>lookup</c> operation. Since the <c>any</c>
 
524
      type can be rather expensive we can use a <c>struct</c> or a <c>union</c> instead.
 
525
      If we intend to return the same information about a employee every time we can
 
526
      use a struct. Let us assume that the DB contains the name, address, employee 
 
527
      number and department.</p>
 
528
    <code type="none"><![CDATA[
 
529
// DB IDL
 
530
#ifndef _DB_IDL_
 
531
#define _DB_IDL_
 
532
module DB {
 
533
 
 
534
  typedef unsigned long EmployeeNo;
 
535
 
 
536
  enum Department {Department1, Department2};
 
537
 
 
538
  struct employee {
 
539
        EmployeeNo No;
 
540
        string Name; 
 
541
        string Address; 
 
542
        Department Dpt;
 
543
  };
 
544
 
 
545
  typedef employee EmployeeData;
 
546
 
 
547
  interface CommonUser {
 
548
 
 
549
     EmployeeData lookup(in EmployeeNo ENo);
 
550
 
 
551
  };
 
552
 
 
553
  interface Administrator : CommonUser {
 
554
 
 
555
     void delete(in EmployeeNo ENo);
 
556
 
 
557
  };
 
558
 
 
559
  interface Access {
 
560
 
 
561
      typedef string<10> UserID;
 
562
      typedef string<10> Password;
 
563
 
 
564
      // Since Administrator inherits from CommonUser
 
565
      // the returned Object can be of either type.
 
566
      CommonUser logon(in UserID ID, in Password PW);
 
567
 
 
568
  };
 
569
 
 
570
};
 
571
#endif    ]]></code>
 
572
    <p>We can also define exceptions (i.e. not system exception) thrown by
 
573
      each interface. Since exceptions are thoroughly described in the chapter
 
574
      <seealso marker="ch_exceptions">System and User Defined Exceptions</seealso>,
 
575
      we choose not to. Hence, we are now ready to compile our IDL-file by 
 
576
      invoking:</p>
 
577
    <pre>
 
578
$ <input>erlc DB.idl</input>
 
579
    </pre>
 
580
    <p>or:</p>
 
581
    <pre>
 
582
$ <input>erl</input>
 
583
Erlang (BEAM) emulator version 5.1.1 [threads:0]
 
584
 
 
585
Eshell V5.1.1  (abort with ^G)
 
586
1> <input>ic:gen('DB').</input>
 
587
ok
 
588
2> <input>halt().</input>
 
589
    </pre>
 
590
    <p>The next step is to implement our servers. But, to be able to do that,
 
591
      we need to know how we can access data type definitions. For example,
 
592
      since a struct is mapped to an Erlang record we must include an hrl-file
 
593
      in our callback module.</p>
 
594
  </section>
 
595
 
 
596
  <section>
 
597
    <title>Scoped Names and Generated Files</title>
 
598
 
 
599
    <section>
 
600
      <title>Scoped Names</title>
 
601
      <p>Within a scope all identifiers must be unique. The following kinds of
 
602
        definitions form scopes in the OMG IDL:</p>
 
603
      <list type="bulleted">
 
604
        <item><em>module</em></item>
 
605
        <item><em>interface</em></item>
 
606
        <item><em>operation</em></item>
 
607
        <item><em>valuetype</em></item>
 
608
        <item><em>struct</em></item>
 
609
        <item><em>union</em></item>
 
610
        <item><em>exception</em></item>
 
611
      </list>
 
612
      <p>For example, since enumerants do not form a scope, the following IDL code
 
613
        is not valid:</p>
 
614
      <code type="none">
 
615
module MyModule {
 
616
     // 'two' is not unique
 
617
     enum MyEnum {one, two};
 
618
     enum MyOtherEnum {two, three};
 
619
};
 
620
      </code>
 
621
      <p>But, since Erlang only has two levels of scope, <em>module</em> and 
 
622
        <em>function</em>, the OMG IDL scope is mapped as follows:</p>
 
623
      <list type="bulleted">
 
624
        <item><em>Function Scope</em> - used for constants, operations and attributes.</item>
 
625
        <item><em>Erlang Module Scope</em> - the Erlang module scope
 
626
         handles the remaining OMG IDL scopes.</item>
 
627
      </list>
 
628
      <p>An Erlang module, corresponding to an IDL global name, is derived by 
 
629
        converting occurencies of "::" to underscore, and eliminating
 
630
        the leading "::". Hence, accessing <c>MyEnum</c> from another module, one 
 
631
        use <c>MyModule::MyEnum</c></p>
 
632
      <p>For example, an operation <c>foo</c> defined in interface <c>I</c>, which
 
633
        is defined in module <c>M</c>, would be written in IDL as <c>M::I::foo</c>
 
634
        and as <c>'M_I':foo</c> in Erlang - <c>foo</c> is the function
 
635
        name and <c>'M_I'</c> is the name of the Erlang module. Applying this
 
636
        knowledge to a stripped version of the DB.idl gives:</p>
 
637
      <code type="none"><![CDATA[
 
638
// DB IDL
 
639
#ifndef _DB_IDL_
 
640
#define _DB_IDL_
 
641
// ++ topmost scope ++ 
 
642
// IC generates oe_XX.erl and oe_XX.hrl.
 
643
// XX is equal to the name of the IDL-file.
 
644
// Tips: create one IDL-file for each top module
 
645
// and give the file the same name (DB.idl).
 
646
// The oe_XX.erl module is used to register data
 
647
// in the IFR.
 
648
module DB {
 
649
 
 
650
  // ++ Module scope ++
 
651
  // To access 'EmployeeNo' from another scope, use:
 
652
  // DB::EmployeeNo, DB::Access etc.
 
653
  typedef unsigned long EmployeeNo;
 
654
 
 
655
  enum Department {Department1, Department2};
 
656
 
 
657
  // Definitions of this struct is contained in:
 
658
  // DB.hrl
 
659
  // Access functions exported by:
 
660
  // DB_employee.erl
 
661
  struct employee {
 
662
     ... CUT ...
 
663
  };
 
664
 
 
665
  typedef employee EmployeeData;
 
666
 
 
667
  ... CUT ...
 
668
 
 
669
  // If this interface should inherit an interface
 
670
  // in another module (e.g. OtherModule) use:
 
671
  // interface Access : OtherModule::OtherInterface
 
672
  interface Access {
 
673
 
 
674
      // ++ interface scope ++
 
675
      // Types within this scope is accessible via:
 
676
      // DB::Access::UserID
 
677
      // The Stub/Skeleton for this interface is
 
678
      // placed in the module:
 
679
      // DB_Access.erl
 
680
      typedef string<10> UserID;
 
681
      typedef string<10> Password;
 
682
 
 
683
      // Since Administrator inherits from CommonUser
 
684
      // the returned Object can be of either type.
 
685
      // This operation is exported from:
 
686
      // DB_Access.erl
 
687
      CommonUser logon(in UserID ID, in Password PW);
 
688
 
 
689
  };
 
690
 
 
691
};
 
692
#endif      ]]></code>
 
693
      <p>Using underscores in IDL names can lead to ambiguities
 
694
        due to the name mapping described above. It is advisable to 
 
695
        avoid the use of underscores in identifiers. For example, the following
 
696
        definition would generate two structures namned <c>x_y_z</c>.</p>
 
697
      <code type="none">
 
698
module x {
 
699
 
 
700
    struct y_z {
 
701
\011...
 
702
    };
 
703
 
 
704
    interface y {
 
705
 
 
706
\011struct z {
 
707
\011    ...
 
708
\011};
 
709
    };
 
710
};
 
711
      </code>
 
712
    </section>
 
713
 
 
714
    <section>
 
715
      <title>Generated Files</title>
 
716
      <p>Several files can be generated for each scope.</p>
 
717
      <list type="bulleted">
 
718
        <item>An Erlang source code file (<c>.erl</c>) is generated
 
719
         for top level scope as well as the Erlang header file.</item>
 
720
        <item>An Erlang header file (<c>.hrl</c>) will be generated for 
 
721
         each scope. The header file will contain record definitions 
 
722
         for all <c>struct</c>, <c>union</c> and <c>exception</c> 
 
723
         types in that scope.</item>
 
724
        <item>Modules that contain at least one constant definition,
 
725
         will produce Erlang source code files (<c>.erl</c>).
 
726
         That Erlang file will contain constant functions for 
 
727
         that scope.
 
728
         Modules that contain no constant definitions are considered
 
729
         empty and no code will be produced for them, but only for
 
730
         their included modules/interfaces.</item>
 
731
        <item>Interfaces will produce Erlang source code files (<c>.erl</c>),
 
732
         this code will contain all operation stub code and implementation
 
733
         functions.</item>
 
734
        <item>In addition to the scope-related files, an Erlang source file will
 
735
         be generated for each definition of the types <c>struct</c>,
 
736
        <c>union</c> and <c>exception</c> (these are the types that
 
737
         will be represented in Erlang as records).
 
738
         This file will contain special access functions for that record.</item>
 
739
        <item>The top level scope will produce two files, one header file
 
740
         (<c>.hrl</c>) and one Erlang source file (<c>.erl</c>).
 
741
         These files are named as the IDL file, prefixed with <c>oe_</c>.</item>
 
742
      </list>
 
743
      <p>After compiling DB.idl, the following files have been generated:</p>
 
744
      <list type="bulleted">
 
745
        <item><c>oe_DB.hrl</c> and <c>oe_DB.erl</c> for the top scope level.</item>
 
746
        <item><c>DB.hrl</c> for the module <c>DB</c>.</item>
 
747
        <item><c>DB_Access.hrl</c> and <c>DB_Access.erl</c> for the interface 
 
748
        <c>DB_Access</c>.</item>
 
749
        <item><c>DB_CommonUser.hrl</c> and <c>DB_CommonUser.erl</c> for the interface 
 
750
        <c>DB_CommonUser</c>.</item>
 
751
        <item><c>DB_Administrator.hrl</c> and <c>DB_Administrator.erl</c> for the interface 
 
752
        <c>DB_Administrator</c>.</item>
 
753
        <item><c>DB_employee.erl</c> for the structure <c>employee</c> in module 
 
754
        <c>DB</c>.</item>
 
755
      </list>
 
756
      <p>Since the <c>employee</c> struct is defined in the top level scope,
 
757
        the Erlang record definition is found in <c>DB.hrl</c>. IC also generates
 
758
        stubs/skeletons (e.g. <c>DB_CommonUser.erl</c>) and access functions for
 
759
        some datatypes (e.g. <c>DB_employee.erl</c>). How the stubs/skeletons are
 
760
        used is thoroughly described in
 
761
        <seealso marker="ch_stubs">Stubs/Skeletons</seealso> and
 
762
        <seealso marker="Module_Interface">Module_Interface</seealso>.</p>
 
763
    </section>
 
764
  </section>
 
765
 
 
766
  <section>
 
767
    <title>Typecode, Identity and Name Access Functions</title>
 
768
    <p>As mentioned in a previous section, <c>struct</c>, <c>union</c> and 
 
769
      <c>exception</c> types yield record definitions and access code 
 
770
      for that record. 
 
771
      For <c>struct</c>, <c>union</c>, <c>exception</c>, <c>array</c> and 
 
772
      <c>sequence</c> types, a special file is generated that holds access
 
773
      functions for <c>TypeCode</c>, <c>Identity</c> and <c>Name</c>.
 
774
      These functions are put in the file corresponding to the scope where 
 
775
      they are defined. For example, the module <c>DB_employee.erl</c>, 
 
776
      representing the <c>employee</c> struct, exports the following functions:</p>
 
777
    <list type="bulleted">
 
778
      <item>tc/0 - returns the type code for the struct.</item>
 
779
      <item>id/0 - returns the IFR identity of the struct. In this case
 
780
       the returned value is <c>"IDL:DB/employee:1.0"</c>, but
 
781
       if the struct was defined in the scope of <c>CommonUser</c>,
 
782
       the result would be <c>"IDL:DB/CommonUser/employee:1.0"</c>.
 
783
       However, the user usually do not need to know the Id, just
 
784
       which Erlang module contains the correct Id.</item>
 
785
      <item>name/0 - returns the scoped name of the struct. The <c>employee</c>
 
786
       struct name is <c>"DB_employee"</c>.</item>
 
787
    </list>
 
788
    <p><term id="Type Codes"><termdef>Type codes give a complete description  of the type including all its components and structure.</termdef></term>are, for example, used in <seealso marker="any">Any</seealso> values.
 
789
      Hence, we can encapsulate the <c>employee</c> struct in an <c>any</c>
 
790
      type by:</p>
 
791
    <code type="none">
 
792
%% Erlang code
 
793
....
 
794
AnEmployee = #'DB_employee'{'No'      = 1,
 
795
                            'Name'    = "Adam Ivan Kendall",
 
796
                            'Address' = "Rasunda, Solna",
 
797
                            'Dpt'     = 'Department1'},
 
798
EmployeeTC = 'DB_employee':tc(),
 
799
EmployeeAny = any:create(EmployeeTC, AnEmployee),
 
800
....
 
801
    </code>
 
802
    <p>For more information, see the
 
803
      <seealso marker="#tk_values">Type Code listing</seealso>.</p>
 
804
  </section>
 
805
 
 
806
  <section>
 
807
    <title>References to Constants</title>
 
808
    <p>Constants are generated as Erlang functions, and are accessed by a
 
809
      single function call. The functions are put in the file
 
810
      corresponding to the scope where they are defined. There is no
 
811
      need for an object to be started to access a constant.</p>
 
812
    <p>Example:</p>
 
813
    <code type="none">
 
814
// m.idl
 
815
module m {
 
816
    const float pi = 3.14;
 
817
 
 
818
    interface i {
 
819
\011const float pi = 3.1415;
 
820
    };
 
821
};
 
822
    </code>
 
823
    <p>Since the two constants are defined in different scopes, the IDL code
 
824
      above is valid, but not necessarily a good approach. After compiling
 
825
      <c>m.idl</c>, the constant definitions can be extracted by invoking:</p>
 
826
    <pre>
 
827
$ <input>erlc m.idl</input>
 
828
$ <input>erlc m.erl</input>
 
829
$ <input>erl</input>
 
830
Erlang (BEAM) emulator version 5.1.1 [threads:0]
 
831
 
 
832
Eshell V5.1.1  (abort with ^G)
 
833
1> <input>m:pi().</input>
 
834
3.14
 
835
2> <input>m_i:pi().</input>
 
836
3.1415
 
837
3> <input>halt().</input>
 
838
    </pre>
 
839
  </section>
 
840
 
 
841
  <section>
 
842
    <title>References to Objects Defined in OMG IDL</title>
 
843
    <p>Objects are accessed by object references. An object reference
 
844
      is an opaque Erlang term created and maintained by the ORB.</p>
 
845
    <p>Objects are implemented by providing implementations for all
 
846
      operations and attributes of the Object, <seealso marker="#op_impl">see operation implementation</seealso>.</p>
 
847
  </section>
 
848
 
 
849
  <section>
 
850
    <title>Exceptions</title>
 
851
    <p>Exceptions are handled as Erlang catch and throws. Exceptions
 
852
      are translated to messages over an IIOP bridge but converted
 
853
      back to a throw on the receiving side. Object implementations
 
854
      that invoke operations on other objects must be aware of the
 
855
      possibility of a non-local return. This includes invocation of
 
856
      ORB and IFR services. See also the
 
857
      <seealso marker="ch_exceptions">Exceptions</seealso> section.</p>
 
858
    <p>Exception parameters are mapped as an Erlang record and accessed
 
859
      as such.</p>
 
860
    <p>An object implementation that raises an exception will use the
 
861
      <c>corba:raise/1</c> function, passing the exception record as
 
862
      parameter.</p>
 
863
  </section>
 
864
 
 
865
  <section>
 
866
    <title>Access to Attributes</title>
 
867
    <p>Attributes are accessed through their access functions. An
 
868
      attribute implicitly defines the <c>_get</c> and <c>_set</c>
 
869
      operations. These operations are handled in the same way as
 
870
      normal operations. The <c>_get</c> operation is defined as a <c>readonly</c> 
 
871
      attribute.</p>
 
872
    <code type="none">
 
873
readonly attribute long RAttribute;
 
874
attribute long RWAttribute;
 
875
    </code>
 
876
    <p>The <c>RAttribute</c> requires that you implement, in your call-back module,
 
877
      <c>_get_RAttribute</c>. For the <c>RWAttribute</c> it is necessary to implement
 
878
      <c>_get_RWAttribute</c> and <c>_set_RWAttribute</c>.</p>
 
879
  </section>
 
880
 
 
881
  <section>
 
882
    <title>Invocations of Operations</title>
 
883
    <marker id="op_impl"></marker>
 
884
    <p>A standard Erlang <c>gen_server</c> behavior is used for
 
885
      object implementation. The <c>gen_server</c> state is then
 
886
      used as the object internal state. Implementation of the object 
 
887
      function is achieved by implementing its methods and attribute operations.
 
888
      These functions will usually have the internal state as their first parameter, 
 
889
      followed by any <c>in</c> and <c>inout</c> parameters. </p>
 
890
    <p>Do not confuse the
 
891
      object internal state with its object reference. The object internal state is
 
892
      an Erlang term which has a format defined by the user.</p>
 
893
    <note>
 
894
      <p>It is is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
 
895
    </note>
 
896
    <p>A function call will invoke an operation. The first
 
897
      parameter of the function should be the object reference and then
 
898
      all <c>in</c> and <c>inout</c> parameters follow in the same
 
899
      order as specified in the IDL specification. The result will be a return value
 
900
      unless the function has <c>inout</c> or <c>out</c> parameters specified; 
 
901
      in which case, a tuple of the return value, followed by the parameters will
 
902
      be returned.</p>
 
903
    <p>Example:</p>
 
904
    <code type="none">
 
905
// IDL
 
906
module m {
 
907
  interface i {
 
908
      readonly attribute long RAttribute;
 
909
      attribute long RWAttribute;
 
910
      long foo(in short a);
 
911
      long bar(in char c, inout string s, out long count);
 
912
      void baz(out long Id);
 
913
  };
 
914
};
 
915
    </code>
 
916
    <p>Is used in Erlang as :</p>
 
917
    <code type="none">
 
918
%% Erlang code
 
919
....
 
920
Obj = ...    %% get object reference
 
921
RAttr  = m_i:'_get_RAttribute'(Obj),
 
922
RWAttr = m_i:'_get_RWAttribute'(Obj),
 
923
ok = m_i:'_set_RWAttribute'(Obj, Long),
 
924
R1 = m_i:foo(Obj, 55),
 
925
{R2, S, Count} = m_i:bar(Obj, $a, "hello"),
 
926
....
 
927
    </code>
 
928
    <p>Note how the <c>inout</c> parameter is passed <em>and</em>
 
929
      returned. There is no way to use a single occurrence of a
 
930
      variable for this in Erlang. Also note, that <c>ok</c>, Orber's 
 
931
      representation of the IDL-type <c>void</c>, must be returned by
 
932
      <c>baz</c> and <c>'_set_RWAttribute'</c>. 
 
933
      These operations can be implemented in the call-back module as:</p>
 
934
    <code type="none">
 
935
'_set_RWAttribute'(State, Long) ->
 
936
    {reply, ok, State}.
 
937
 
 
938
'_get_RWAttribute'(State) ->
 
939
    {reply, Long, State}.
 
940
 
 
941
'_get_RAttribute'(State) ->
 
942
    {reply, Long, State}.
 
943
 
 
944
foo(State, AShort) ->
 
945
    {reply, ALong, State}.
 
946
 
 
947
bar(State, AShort, AString) ->
 
948
    {reply, {ALong, "MyString", ALong}, State}.
 
949
 
 
950
baz(State) ->
 
951
    {reply, {ok, AId}, State}.
 
952
    </code>
 
953
    <p>The operations may require more arguments (depends on IC options used). For
 
954
      more information, see <seealso marker="ch_stubs">Stubs/Skeletons</seealso>
 
955
      and <seealso marker="Module_Interface">Module_Interface</seealso>.</p>
 
956
    <warning>
 
957
      <p>A function can also be defined to be <c>oneway</c>, i.e. 
 
958
        asynchronous. But, since the behavior of a oneway operation is not
 
959
        defined in the OMG specifications (i.e. the behavior can differ depending on
 
960
        which other ORB Orber is communicating with), one should avoid using it.</p>
 
961
    </warning>
 
962
  </section>
 
963
 
 
964
  <section>
 
965
    <title>Implementing the DB Application</title>
 
966
    <p>Now we are ready to implement the call-back modules. There are three modules
 
967
      we must create:</p>
 
968
    <list type="bulleted">
 
969
      <item>DB_Access_impl.erl</item>
 
970
      <item>DB_CommonUser_impl.erl</item>
 
971
      <item>DB_Administrator_impl.erl</item>
 
972
    </list>
 
973
    <p>An easy way to accomplish that, is to use the IC backend <c>erl_template</c>,
 
974
      which will generate a complete call-back module. One should also add
 
975
      the same compile options, for example <c>this</c> or <c>from</c>,
 
976
      used when generating the stub/skeleton modules:</p>
 
977
    <code type="none">
 
978
$> erlc +"{be,erl_template}" DB.idl
 
979
    </code>
 
980
    <p>We begin with implementing the <c>DB_Access_impl.erl</c> module, which,
 
981
      if we used <c>erl_template</c>, will look like the following. All we need
 
982
      to do is to add the logic to the <c>logon</c> operation.</p>
 
983
    <code type="none"><![CDATA[
 
984
%%----------------------------------------------------------------------
 
985
%% <LICENSE>
 
986
%% 
 
987
%%     $Id$
 
988
%%
 
989
%%----------------------------------------------------------------------
 
990
%% Module       : DB_Access_impl.erl
 
991
%% 
 
992
%% Source       : /home/user/example/DB.idl
 
993
%% 
 
994
%% Description  : 
 
995
%% 
 
996
%% Creation date: 2005-05-20
 
997
%%
 
998
%%----------------------------------------------------------------------
 
999
-module('DB_Access_impl').
 
1000
 
 
1001
-export([logon/3]).
 
1002
 
 
1003
%%----------------------------------------------------------------------
 
1004
%% Internal Exports
 
1005
%%----------------------------------------------------------------------
 
1006
-export([init/1,
 
1007
         terminate/2,
 
1008
         code_change/3,
 
1009
         handle_info/2]).
 
1010
 
 
1011
%%----------------------------------------------------------------------
 
1012
%% Include Files
 
1013
%%----------------------------------------------------------------------
 
1014
 
 
1015
 
 
1016
%%----------------------------------------------------------------------
 
1017
%% Macros
 
1018
%%----------------------------------------------------------------------
 
1019
 
 
1020
 
 
1021
%%----------------------------------------------------------------------
 
1022
%% Records
 
1023
%%----------------------------------------------------------------------
 
1024
-record(state, {}).
 
1025
 
 
1026
%%======================================================================
 
1027
%% API Functions
 
1028
%%======================================================================
 
1029
%%----------------------------------------------------------------------
 
1030
%% Function   : logon/3
 
1031
%% Arguments  : State - term()
 
1032
%%              ID = String()
 
1033
%%              PW = String()
 
1034
%% Returns    : ReturnValue = OE_Reply
 
1035
%%              OE_Reply = Object_Ref()
 
1036
%% Raises     : 
 
1037
%% Description: 
 
1038
%%----------------------------------------------------------------------
 
1039
logon(State, ID, PW) ->
 
1040
\011%% Check if the ID/PW is valid and what 
 
1041
\011%% type of user it is (Common or Administrator).
 
1042
\011OE_Reply
 
1043
            = case check_user(ID, PW) of
 
1044
\011         {ok, administrator} ->
 
1045
\011            'DB_Administrator':oe_create();
 
1046
\011         {ok, common} ->
 
1047
\011            'DB_CommonUser':oe_create();
 
1048
\011         error ->
 
1049
\011            %% Here we should throw an exception              
 
1050
 \011           corba:raise(....)
 
1051
        end,
 
1052
\011{reply, OE_Reply, State}.
 
1053
 
 
1054
%%======================================================================
 
1055
%% Internal Functions
 
1056
%%======================================================================
 
1057
%%----------------------------------------------------------------------
 
1058
%% Function   : init/1
 
1059
%% Arguments  : Env = term()
 
1060
%% Returns    : {ok, State}          |
 
1061
%%              {ok, State, Timeout} |
 
1062
%%              ignore               |
 
1063
%%              {stop, Reason}
 
1064
%% Raises     : -
 
1065
%% Description: Initiates the server
 
1066
%%----------------------------------------------------------------------
 
1067
init(_Env) ->
 
1068
\011{ok, #state{}}.
 
1069
 
 
1070
 
 
1071
%%----------------------------------------------------------------------
 
1072
%% Function   : terminate/2
 
1073
%% Arguments  : Reason = normal | shutdown | term()
 
1074
%%              State = term()
 
1075
%% Returns    : ok
 
1076
%% Raises     : -
 
1077
%% Description: Invoked when the object is terminating.
 
1078
%%----------------------------------------------------------------------
 
1079
terminate(_Reason, _State) ->
 
1080
\011ok.
 
1081
 
 
1082
 
 
1083
%%----------------------------------------------------------------------
 
1084
%% Function   : code_change/3
 
1085
%% Arguments  : OldVsn = undefined | term()
 
1086
%%              State = NewState = term()
 
1087
%%              Extra = term()
 
1088
%% Returns    : {ok, NewState}
 
1089
%% Raises     : -
 
1090
%% Description: Invoked when the object should update its internal state
 
1091
%%              due to code replacement.
 
1092
%%----------------------------------------------------------------------
 
1093
code_change(_OldVsn, State, _Extra) ->
 
1094
\011{ok, State}.
 
1095
 
 
1096
 
 
1097
%%----------------------------------------------------------------------
 
1098
%% Function   : handle_info/2
 
1099
%% Arguments  : Info = normal | shutdown | term()
 
1100
%%              State = NewState = term()
 
1101
%% Returns    : {noreply, NewState}          |
 
1102
%%              {noreply, NewState, Timeout} |
 
1103
%%              {stop, Reason, NewState}
 
1104
%% Raises     : -
 
1105
%% Description: Invoked when, for example, the server traps exits.
 
1106
%%----------------------------------------------------------------------
 
1107
handle_info(_Info, State) ->
 
1108
\011{noreply, State}.
 
1109
    ]]></code>
 
1110
    <p>Since <c>DB_Administrator</c> inherits from <c>DB_CommonUser</c>,
 
1111
      we must implement <c>delete</c> in the <c>DB_Administrator_impl.erl</c>
 
1112
      module, and <c>lookup</c> in <c>DB_Administrator_impl.erl</c><em>and</em><c>DB_CommonUser_impl.erl</c>. But wait, is that really necessary? Actually,
 
1113
      it is not. We simple use the IC compile option <em>impl</em>:</p>
 
1114
    <pre>
 
1115
$ <input>erlc +'{{impl, "DB::CommonUser"}, "DBUser_impl"}'  +'{{impl, "DB::Administrator"}, "DBUser_impl"}' DB.idl</input>
 
1116
$ <input>erlc *.erl</input>
 
1117
    </pre>
 
1118
    <p>Instead of creating, and not the least, maintaining two call-back modules,
 
1119
      we only have to deal with <c>DBUser_impl.erl</c>. If we generated the
 
1120
      templates, we simply rename <c>DB_Administrator_impl.erl</c> to
 
1121
      <c>DBUser_impl.erl</c>. See also the
 
1122
      <seealso marker="ch_exceptions">Exceptions</seealso> chapter.
 
1123
      In the following example, only the implementation of the API functios
 
1124
      are shown:</p>
 
1125
    <code type="none">
 
1126
%%======================================================================
 
1127
%% API Functions
 
1128
%%======================================================================
 
1129
%%----------------------------------------------------------------------
 
1130
%% Function   : delete/2
 
1131
%% Arguments  : State - term()
 
1132
%%              ENo = unsigned_Long()
 
1133
%% Returns    : ReturnValue = ok
 
1134
%% Raises     : 
 
1135
%% Description: 
 
1136
%%----------------------------------------------------------------------
 
1137
delete(State, ENo) ->
 
1138
        %% How we access the DB, for example mnesia, is not shown here.
 
1139
        case delete_employee(No) of
 
1140
            ok ->
 
1141
                {reply, ok, State};
 
1142
            error ->
 
1143
                %% Here we should throw an exception if
 
1144
                %% there is no match.
 
1145
                corba:raise(....)
 
1146
        end.
 
1147
 
 
1148
%%----------------------------------------------------------------------
 
1149
%% Function   : lookup/2
 
1150
%% Arguments  : State - term()
 
1151
%%              ENo = unsigned_Long()
 
1152
%% Returns    : ReturnValue = OE_Reply
 
1153
%%              OE_Reply = #'DB_employee'{No,Name,Address,Dpt}
 
1154
%%              No = unsigned_Long()
 
1155
%%              Name = String()
 
1156
%%              Address = String()
 
1157
%%              Dpt = Department
 
1158
%%              Department = 'Department1' | 'Department2' 
 
1159
%% Raises     : 
 
1160
%% Description: 
 
1161
%%----------------------------------------------------------------------
 
1162
lookup(State, ENo) ->
 
1163
        %% How we access the DB, for example mnesia, is not shown here.
 
1164
        case lookup_employee(ENo) of
 
1165
            %% We assume that we receive a 'DB_employee' struct
 
1166
            {ok, Employee} ->
 
1167
                OE_Reply = Employee,
 
1168
                {reply, OE_Reply, State};
 
1169
            error ->
 
1170
                %% Here we should throw an exception if
 
1171
                %% there is no match.
 
1172
                corba:raise(....)
 
1173
        end.
 
1174
    </code>
 
1175
    <p>After you have compiled both call-back modules, and implemented the missing
 
1176
      functionality (e.g. lookup_employee/1), we can test our application:</p>
 
1177
    <code type="none">
 
1178
%% Erlang code
 
1179
....
 
1180
%% Create an Access object
 
1181
Acc = 'DB_Access':oe_create(),
 
1182
 
 
1183
%% Login is Common user and Administrator
 
1184
Adm = 'DB_Access':logon(A, "admin", "pw"),
 
1185
Com = 'DB_Access':logon(A, "comm", "pw"),
 
1186
 
 
1187
%% Lookup existing employee
 
1188
Employee = 'DB_Administrator':lookup(Adm, 1),
 
1189
Employee = 'DB_CommonUser':lookup(Adm, 1),
 
1190
 
 
1191
%% If we try the same using the DB_CommonUser interface 
 
1192
%% it result in an exit since that operation is not exported.
 
1193
{'EXIT', _} = (catch 'DB_CommonUser':delete(Adm, 1)),
 
1194
 
 
1195
%% Try to delete the employee via the CommonUser Object
 
1196
{'EXCEPTION', _} = (catch 'DB_Administrator':delete(Com, 1)),
 
1197
 
 
1198
%% Invoke delete operation on the Administrator object
 
1199
ok = 'DB_Administrator':delete(Adm, 1),
 
1200
....
 
1201
    </code>
 
1202
  </section>
 
1203
 
 
1204
  <section>
 
1205
    <title>Reserved Compiler Names and Keywords</title>
 
1206
    <marker id="key_words"></marker>
 
1207
    <p>The use of some names is  strongly discouraged due to 
 
1208
      ambiguities. However, the use of some names is prohibited 
 
1209
      when using the Erlang mapping , as they are strictly reserved for IC.</p>
 
1210
    <p>IC reserves all identifiers starting with <c>OE_</c> and <c>oe_</c> 
 
1211
      for internal use.</p>
 
1212
    <p>Note also, that an identifier in IDL can  contain alphabetic,
 
1213
      digits and underscore characters, but the first character 
 
1214
      <em>must</em> be alphabetic.
 
1215
      </p>
 
1216
    <p>The OMG defines a set of reserved words, shown below, for use as keywords. 
 
1217
      These may <em>not</em> be used as, for example, identifiers. The keywords
 
1218
      which are not in bold face was introduced in the OMG CORBA-3.0 
 
1219
      specification.</p>
 
1220
    <table>
 
1221
      <row>
 
1222
        <cell align="left" valign="middle"><em>abstract</em></cell>
 
1223
        <cell align="left" valign="middle"><em>exception</em></cell>
 
1224
        <cell align="left" valign="middle"><em>inout</em></cell>
 
1225
        <cell align="left" valign="middle">provides</cell>
 
1226
        <cell align="left" valign="middle"><em>truncatable</em></cell>
 
1227
      </row>
 
1228
      <row>
 
1229
        <cell align="left" valign="middle"><em>any</em></cell>
 
1230
        <cell align="left" valign="middle">emits</cell>
 
1231
        <cell align="left" valign="middle"><em>interface</em></cell>
 
1232
        <cell align="left" valign="middle"><em>public</em></cell>
 
1233
        <cell align="left" valign="middle"><em>typedef</em></cell>
 
1234
      </row>
 
1235
      <row>
 
1236
        <cell align="left" valign="middle"><em>attribute</em></cell>
 
1237
        <cell align="left" valign="middle"><em>enum</em></cell>
 
1238
        <cell align="left" valign="middle"><em>local</em></cell>
 
1239
        <cell align="left" valign="middle">publishes</cell>
 
1240
        <cell align="left" valign="middle">typeid</cell>
 
1241
      </row>
 
1242
      <row>
 
1243
        <cell align="left" valign="middle"><em>boolean</em></cell>
 
1244
        <cell align="left" valign="middle">eventtype</cell>
 
1245
        <cell align="left" valign="middle"><em>long</em></cell>
 
1246
        <cell align="left" valign="middle"><em>raises</em></cell>
 
1247
        <cell align="left" valign="middle">typeprefix</cell>
 
1248
      </row>
 
1249
      <row>
 
1250
        <cell align="left" valign="middle"><em>case</em></cell>
 
1251
        <cell align="left" valign="middle"><em>factory</em></cell>
 
1252
        <cell align="left" valign="middle"><em>module</em></cell>
 
1253
        <cell align="left" valign="middle"><em>readonly</em></cell>
 
1254
        <cell align="left" valign="middle"><em>unsigned</em></cell>
 
1255
      </row>
 
1256
      <row>
 
1257
        <cell align="left" valign="middle"><em>char</em></cell>
 
1258
        <cell align="left" valign="middle"><em>FALSE</em></cell>
 
1259
        <cell align="left" valign="middle">multiple</cell>
 
1260
        <cell align="left" valign="middle">setraises</cell>
 
1261
        <cell align="left" valign="middle"><em>union</em></cell>
 
1262
      </row>
 
1263
      <row>
 
1264
        <cell align="left" valign="middle">component</cell>
 
1265
        <cell align="left" valign="middle">finder</cell>
 
1266
        <cell align="left" valign="middle"><em>native</em></cell>
 
1267
        <cell align="left" valign="middle"><em>sequence</em></cell>
 
1268
        <cell align="left" valign="middle">uses</cell>
 
1269
      </row>
 
1270
      <row>
 
1271
        <cell align="left" valign="middle"><em>const</em></cell>
 
1272
        <cell align="left" valign="middle"><em>fixed</em></cell>
 
1273
        <cell align="left" valign="middle"><em>Object</em></cell>
 
1274
        <cell align="left" valign="middle"><em>short</em></cell>
 
1275
        <cell align="left" valign="middle"><em>ValueBase</em></cell>
 
1276
      </row>
 
1277
      <row>
 
1278
        <cell align="left" valign="middle">consumes</cell>
 
1279
        <cell align="left" valign="middle"><em>float</em></cell>
 
1280
        <cell align="left" valign="middle"><em>octet</em></cell>
 
1281
        <cell align="left" valign="middle"><em>string</em></cell>
 
1282
        <cell align="left" valign="middle"><em>valuetype</em></cell>
 
1283
      </row>
 
1284
      <row>
 
1285
        <cell align="left" valign="middle"><em>context</em></cell>
 
1286
        <cell align="left" valign="middle">getraises</cell>
 
1287
        <cell align="left" valign="middle"><em>oneway</em></cell>
 
1288
        <cell align="left" valign="middle"><em>struct</em></cell>
 
1289
        <cell align="left" valign="middle"><em>void</em></cell>
 
1290
      </row>
 
1291
      <row>
 
1292
        <cell align="left" valign="middle"><em>custom</em></cell>
 
1293
        <cell align="left" valign="middle">home</cell>
 
1294
        <cell align="left" valign="middle"><em>out</em></cell>
 
1295
        <cell align="left" valign="middle"><em>supports</em></cell>
 
1296
        <cell align="left" valign="middle"><em>wchar</em></cell>
 
1297
      </row>
 
1298
      <row>
 
1299
        <cell align="left" valign="middle"><em>default</em></cell>
 
1300
        <cell align="left" valign="middle">import</cell>
 
1301
        <cell align="left" valign="middle">primarykey</cell>
 
1302
        <cell align="left" valign="middle"><em>switch</em></cell>
 
1303
        <cell align="left" valign="middle"><em>wstring</em></cell>
 
1304
      </row>
 
1305
      <row>
 
1306
        <cell align="left" valign="middle"><em>double</em></cell>
 
1307
        <cell align="left" valign="middle"><em>in</em></cell>
 
1308
        <cell align="left" valign="middle"><em>private</em></cell>
 
1309
        <cell align="left" valign="middle"><em>TRUE</em></cell>
 
1310
        <cell align="left" valign="middle"></cell>
 
1311
      </row>
 
1312
      <tcaption>OMG IDL keywords</tcaption>
 
1313
    </table>
 
1314
    <p>The keywords listed above must be written exactly as shown. Any usage
 
1315
      of identifiers that collide with a keyword is illegal. For example,
 
1316
      <em>long</em> is a valid keyword; <em>Long</em> and <em>LONG</em> are
 
1317
      illegal as keywords and identifiers. But, since the OMG must be able
 
1318
      to expand the IDL grammar, it is possible to use <em>Escaped  Identifiers</em>. For example, it is not unlikely that <c>native</c>
 
1319
      have been used in IDL-specifications as identifiers. One option is to
 
1320
      change all occurances to <c>myNative</c>. Usually, it is necessary
 
1321
      to change programming language code that depends upon that IDL as well.
 
1322
      Since Escaped Identifiers just disable type checking (i.e. if it is a reserved
 
1323
      word or not) and leaves everything else unchanged, it is only necessary to
 
1324
      update the IDL-specification. To escape an identifier, simply prefix it
 
1325
      with <em>_</em>. The following IDL-code is illegal:</p>
 
1326
    <code type="none">
 
1327
typedef string native;
 
1328
interface i {
 
1329
   void foo(in native Arg);
 
1330
   };
 
1331
};
 
1332
    </code>
 
1333
    <p>With Escaped Identifiers the code will look like:</p>
 
1334
    <code type="none">
 
1335
typedef string _native;
 
1336
interface i {
 
1337
   void foo(in _native Arg);
 
1338
   };
 
1339
};
 
1340
    </code>
 
1341
  </section>
 
1342
 
 
1343
  <section>
 
1344
    <title>Type Code Representation</title>
 
1345
    <marker id="tk_values"></marker>
 
1346
    <p>Type Codes are used in <c>any</c> values. To avoid mistakes, you should
 
1347
      use access functions exported by the Data Types modules
 
1348
      (e.g. struct, union etc) or the <seealso marker="orber_tc">orber_tc</seealso>
 
1349
      module.</p>
 
1350
    <table>
 
1351
      <row>
 
1352
        <cell align="left" valign="middle"><em>Type Code</em></cell>
 
1353
        <cell align="left" valign="middle"><em>Example</em></cell>
 
1354
      </row>
 
1355
      <row>
 
1356
        <cell align="left" valign="middle">tk_null</cell>
 
1357
        <cell align="left" valign="middle"></cell>
 
1358
      </row>
 
1359
      <row>
 
1360
        <cell align="left" valign="middle">tk_void</cell>
 
1361
        <cell align="left" valign="middle"></cell>
 
1362
      </row>
 
1363
      <row>
 
1364
        <cell align="left" valign="middle">tk_short</cell>
 
1365
        <cell align="left" valign="middle"></cell>
 
1366
      </row>
 
1367
      <row>
 
1368
        <cell align="left" valign="middle">tk_long</cell>
 
1369
        <cell align="left" valign="middle"></cell>
 
1370
      </row>
 
1371
      <row>
 
1372
        <cell align="left" valign="middle">tk_longlong</cell>
 
1373
        <cell align="left" valign="middle"></cell>
 
1374
      </row>
 
1375
      <row>
 
1376
        <cell align="left" valign="middle">tk_ushort</cell>
 
1377
        <cell align="left" valign="middle"></cell>
 
1378
      </row>
 
1379
      <row>
 
1380
        <cell align="left" valign="middle">tk_ulong</cell>
 
1381
        <cell align="left" valign="middle"></cell>
 
1382
      </row>
 
1383
      <row>
 
1384
        <cell align="left" valign="middle">tk_ulonglong</cell>
 
1385
        <cell align="left" valign="middle"></cell>
 
1386
      </row>
 
1387
      <row>
 
1388
        <cell align="left" valign="middle">tk_float</cell>
 
1389
        <cell align="left" valign="middle"></cell>
 
1390
      </row>
 
1391
      <row>
 
1392
        <cell align="left" valign="middle">tk_double</cell>
 
1393
        <cell align="left" valign="middle"></cell>
 
1394
      </row>
 
1395
      <row>
 
1396
        <cell align="left" valign="middle">tk_boolean</cell>
 
1397
        <cell align="left" valign="middle"></cell>
 
1398
      </row>
 
1399
      <row>
 
1400
        <cell align="left" valign="middle">tk_char</cell>
 
1401
        <cell align="left" valign="middle"></cell>
 
1402
      </row>
 
1403
      <row>
 
1404
        <cell align="left" valign="middle">tk_wchar</cell>
 
1405
        <cell align="left" valign="middle"></cell>
 
1406
      </row>
 
1407
      <row>
 
1408
        <cell align="left" valign="middle">tk_octet</cell>
 
1409
        <cell align="left" valign="middle"></cell>
 
1410
      </row>
 
1411
      <row>
 
1412
        <cell align="left" valign="middle">tk_any</cell>
 
1413
        <cell align="left" valign="middle"></cell>
 
1414
      </row>
 
1415
      <row>
 
1416
        <cell align="left" valign="middle">tk_TypeCode</cell>
 
1417
        <cell align="left" valign="middle"></cell>
 
1418
      </row>
 
1419
      <row>
 
1420
        <cell align="left" valign="middle">tk_Principal</cell>
 
1421
        <cell align="left" valign="middle"></cell>
 
1422
      </row>
 
1423
      <row>
 
1424
        <cell align="left" valign="middle">{tk_objref, IFRId, Name}</cell>
 
1425
        <cell align="left" valign="middle">{tk_objref, "IDL:M1\\I1:1.0", "I1"}</cell>
 
1426
      </row>
 
1427
      <row>
 
1428
        <cell align="left" valign="middle">{tk_struct, IFRId, Name, [{ElemName, ElemTC}]}</cell>
 
1429
        <cell align="left" valign="middle">{tk_struct, "IDL:M1\\S1:1.0", "S1", [{"a", tk_long}, {"b", tk_char}]}</cell>
 
1430
      </row>
 
1431
      <row>
 
1432
        <cell align="left" valign="middle">{tk_union, IFRId, Name, DiscrTC, DefaultNr, [{Label, ElemName, ElemTC}]}         <br></br>
 
1433
Note: DefaultNr tells which of tuples in the case list that is default, or -1 if no default</cell>
 
1434
        <cell align="left" valign="middle">{tk_union, "IDL:U1:1.0", "U1", tk_long, 1, [{1, "a", tk_long}, {default, "b", tk_char}]}</cell>
 
1435
      </row>
 
1436
      <row>
 
1437
        <cell align="left" valign="middle">{tk_enum, IFRId, Name, [ElemName]}</cell>
 
1438
        <cell align="left" valign="middle">{tk_enum, "IDL:E1:1.0", "E1", ["a1", "a2"]}</cell>
 
1439
      </row>
 
1440
      <row>
 
1441
        <cell align="left" valign="middle">{tk_string, Length}</cell>
 
1442
        <cell align="left" valign="middle">{tk_string, 5}</cell>
 
1443
      </row>
 
1444
      <row>
 
1445
        <cell align="left" valign="middle">{tk_wstring, Length}</cell>
 
1446
        <cell align="left" valign="middle">{tk_wstring, 7}</cell>
 
1447
      </row>
 
1448
      <row>
 
1449
        <cell align="left" valign="middle">{tk_fixed, Digits, Scale}</cell>
 
1450
        <cell align="left" valign="middle">{tk_fixed, 3, 2}</cell>
 
1451
      </row>
 
1452
      <row>
 
1453
        <cell align="left" valign="middle">{tk_sequence, ElemTC, Length}</cell>
 
1454
        <cell align="left" valign="middle">{tk_sequence, tk_long, 4}</cell>
 
1455
      </row>
 
1456
      <row>
 
1457
        <cell align="left" valign="middle">{tk_array, ElemTC, Length}</cell>
 
1458
        <cell align="left" valign="middle">{tk_array, tk_char, 9}</cell>
 
1459
      </row>
 
1460
      <row>
 
1461
        <cell align="left" valign="middle">{tk_alias, IFRId, Name, TC}</cell>
 
1462
        <cell align="left" valign="middle">{tk_alias, "IDL:T1:1.0", "T1", tk_short}</cell>
 
1463
      </row>
 
1464
      <row>
 
1465
        <cell align="left" valign="middle">{tk_except, IFRId, Name, [{ElemName, ElemTC}]}</cell>
 
1466
        <cell align="left" valign="middle">{tk_except, "IDL:Exc1:1.0", "Exc1", [{"a", tk_long}, {"b", {tk_string, 0}}]}</cell>
 
1467
      </row>
 
1468
      <tcaption>Type Code tuples</tcaption>
 
1469
    </table>
 
1470
  </section>
 
1471
</chapter>
 
1472