Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 1081

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css">
<title>Erlang -- OMG IDL to Erlang Mapping</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/orber-3.6.24.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>orber</strong><br><strong>User's Guide</strong><br><small>Version 3.6.24</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../../../../doc/js/flipmenu">
<li id="no" title="The Orber Application" expanded="false">The Orber Application<ul>
<li><a href="ch_contents.html">
              Top of chapter
            </a></li>
<li title="Content Overview"><a href="ch_contents.html#id61214">Content Overview</a></li>
<li title="Brief Description of the User's Guide"><a href="ch_contents.html#id62498">Brief Description of the User's Guide</a></li>
</ul>
</li>
<li id="no" title="Introduction to Orber" expanded="false">Introduction to Orber<ul>
<li><a href="ch_introduction.html">
              Top of chapter
            </a></li>
<li title="Overview"><a href="ch_introduction.html#id64790">Overview</a></li>
</ul>
</li>
<li id="no" title="The Orber Application" expanded="false">The Orber Application<ul>
<li><a href="ch_orber_kernel.html">
              Top of chapter
            </a></li>
<li title="ORB Kernel and IIOP "><a href="ch_orber_kernel.html#id57197">ORB Kernel and IIOP </a></li>
<li title="The Object Request Broker (ORB)"><a href="ch_orber_kernel.html#id63374">The Object Request Broker (ORB)</a></li>
<li title="Internet Inter-Object Protocol (IIOP)"><a href="ch_orber_kernel.html#id65057">Internet Inter-Object Protocol (IIOP)</a></li>
</ul>
</li>
<li id="no" title="Interface Repository" expanded="false">Interface Repository<ul>
<li><a href="ch_ifr.html">
              Top of chapter
            </a></li>
<li title="Interface Repository(IFR)"><a href="ch_ifr.html#id64309">Interface Repository(IFR)</a></li>
</ul>
</li>
<li id="no" title="Installing Orber" expanded="false">Installing Orber<ul>
<li><a href="ch_install.html">
              Top of chapter
            </a></li>
<li title="Installation Process "><a href="ch_install.html#id62824">Installation Process </a></li>
<li title="Configuration"><a href="ch_install.html#id74009">Configuration</a></li>
<li title="Firewall Configuration"><a href="ch_install.html#id76130">Firewall Configuration</a></li>
<li title="Interface Configuration"><a href="ch_install.html#id76571">Interface Configuration</a></li>
</ul>
</li>
<li id="loadscrollpos" title="OMG IDL to Erlang Mapping" expanded="true">OMG IDL to Erlang Mapping<ul>
<li><a href="ch_idl_to_erlang_mapping.html">
              Top of chapter
            </a></li>
<li title="OMG IDL to Erlang Mapping - Overview"><a href="ch_idl_to_erlang_mapping.html#id76788">OMG IDL to Erlang Mapping - Overview</a></li>
<li title="OMG IDL Mapping Elements"><a href="ch_idl_to_erlang_mapping.html#id76811">OMG IDL Mapping Elements</a></li>
<li title="Getting Started"><a href="ch_idl_to_erlang_mapping.html#id76868">Getting Started</a></li>
<li title="Basic OMG IDL Types"><a href="ch_idl_to_erlang_mapping.html#id76929">Basic OMG IDL Types</a></li>
<li title="Template OMG IDL Types and Complex Declarators"><a href="ch_idl_to_erlang_mapping.html#id77470">Template OMG IDL Types and Complex Declarators</a></li>
<li title="Constructed OMG IDL Types"><a href="ch_idl_to_erlang_mapping.html#id77956">Constructed OMG IDL Types</a></li>
<li title="Scoped Names and Generated Files"><a href="ch_idl_to_erlang_mapping.html#id78395">Scoped Names and Generated Files</a></li>
<li title="Typecode, Identity and Name Access Functions"><a href="ch_idl_to_erlang_mapping.html#id78787">Typecode, Identity and Name Access Functions</a></li>
<li title="References to Constants"><a href="ch_idl_to_erlang_mapping.html#id78931">References to Constants</a></li>
<li title="References to Objects Defined in OMG IDL"><a href="ch_idl_to_erlang_mapping.html#id78990">References to Objects Defined in OMG IDL</a></li>
<li title="Exceptions"><a href="ch_idl_to_erlang_mapping.html#id79013">Exceptions</a></li>
<li title="Access to Attributes"><a href="ch_idl_to_erlang_mapping.html#id79046">Access to Attributes</a></li>
<li title="Invocations of Operations"><a href="ch_idl_to_erlang_mapping.html#id79103">Invocations of Operations</a></li>
<li title="Implementing the DB Application"><a href="ch_idl_to_erlang_mapping.html#id79262">Implementing the DB Application</a></li>
<li title="Reserved Compiler Names and Keywords"><a href="ch_idl_to_erlang_mapping.html#id79480">Reserved Compiler Names and Keywords</a></li>
<li title="Type Code Representation"><a href="ch_idl_to_erlang_mapping.html#id80225">Type Code Representation</a></li>
</ul>
</li>
<li id="no" title="CosNaming Service" expanded="false">CosNaming Service<ul>
<li><a href="ch_naming_service.html">
              Top of chapter
            </a></li>
<li title="Overview of the CosNaming Service"><a href="ch_naming_service.html#id80888">Overview of the CosNaming Service</a></li>
<li title="The Basic Use-cases of the Naming Service"><a href="ch_naming_service.html#id81031">The Basic Use-cases of the Naming Service</a></li>
<li title="Interoperable Naming Service"><a href="ch_naming_service.html#id81378">Interoperable Naming Service</a></li>
</ul>
</li>
<li id="no" title="How to use security in Orber" expanded="false">How to use security in Orber<ul>
<li><a href="ch_security.html">
              Top of chapter
            </a></li>
<li title="Security in Orber"><a href="ch_security.html#id82238">Security in Orber</a></li>
</ul>
</li>
<li id="no" title="Orber Stubs/Skeletons" expanded="false">Orber Stubs/Skeletons<ul>
<li><a href="ch_stubs.html">
              Top of chapter
            </a></li>
<li title="Orber Stubs and Skeletons Description"><a href="ch_stubs.html#id82459">Orber Stubs and Skeletons Description</a></li>
</ul>
</li>
<li id="no" title="CORBA System and User Defined Exceptions" expanded="false">CORBA System and User Defined Exceptions<ul>
<li><a href="ch_exceptions.html">
              Top of chapter
            </a></li>
<li title="System Exceptions"><a href="ch_exceptions.html#id83036">System Exceptions</a></li>
<li title="User Defined Exceptions"><a href="ch_exceptions.html#id83473">User Defined Exceptions</a></li>
<li title="Throwing Exceptions"><a href="ch_exceptions.html#id83493">Throwing Exceptions</a></li>
<li title="Catching Exceptions"><a href="ch_exceptions.html#id83525">Catching Exceptions</a></li>
</ul>
</li>
<li id="no" title="Orber Interceptors" expanded="false">Orber Interceptors<ul>
<li><a href="ch_interceptors.html">
              Top of chapter
            </a></li>
<li title="Using Interceptors"><a href="ch_interceptors.html#id83634">Using Interceptors</a></li>
<li title="Interceptor Example"><a href="ch_interceptors.html#id83850">Interceptor Example</a></li>
</ul>
</li>
<li id="no" title="OrberWeb" expanded="false">OrberWeb<ul>
<li><a href="ch_orberweb.html">
              Top of chapter
            </a></li>
<li title="Using OrberWeb"><a href="ch_orberweb.html#id84111">Using OrberWeb</a></li>
<li title="Starting OrberWeb"><a href="ch_orberweb.html#id84699">Starting OrberWeb</a></li>
</ul>
</li>
<li id="no" title="Debugging" expanded="false">Debugging<ul>
<li><a href="ch_debugging.html">
              Top of chapter
            </a></li>
<li title="Tools and FAQ"><a href="ch_debugging.html#id84785">Tools and FAQ</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>6 OMG IDL to Erlang Mapping</h1>
  

  <h3><a name="id76788">6.1 
        OMG IDL to Erlang Mapping - Overview</a></h3>
    
    <p>The purpose of OMG IDL, <strong>Interface Definition Language</strong>, mapping
      is to act as translator between platforms and languages. An IDL 
      specification is supposed to describe data types, object types etc.</p>
    <p>CORBA is independent of the programming language used to construct
      clients or implementations. In order to use the ORB, it is
      necessary for programmers to know how to access ORB functionality 
      from their programming languages. It translates different IDL constructs
      to  a specific programming language. This chapter 
      describes the mapping of OMG IDL constructs to the Erlang programming
      language.</p>
  

  <h3><a name="id76811">6.2 
        OMG IDL Mapping Elements</a></h3>
    
    <p>A complete language mapping will allow the programmer to have
      access to all ORB functionality in a way that is convenient for
      a specified programming language. 
      </p>
    <p>All mapping must define the following elements: 
      </p>
    <ul>
      <li>All OMG IDL basic and constructed types</li>
      <li>References to constants defined in OMG IDL</li>
      <li>References to objects defined in OMG IDL</li>
      <li>Invocations of operations, including passing of
       parameters and receiving of results</li>
      <li>Exceptions, including what happens when an operation
       raises an exception and how the exception parameters are
       accessed</li>
      <li>Access to attributes</li>
      <li>Signatures for operations defined by the ORB, such as
       dynamic invocation interface, the object adapters etc.</li>
      <li>Scopes;
       OMG IDL has several levels of scopes, which are mapped to Erlang's 
       two scopes.</li>
    </ul>
  

  <h3><a name="id76868">6.3 
        Getting Started</a></h3>
    
    <p>To begin with, we should decide which type of objects (i.e. servers) we
      need and if two, or more, should export the same functionality. Let us
      assume that we want to create a system for DB (database) access for different
      kind of users. For example, anyone with a valid password may extract 
      data, but only a few may update the DB. Usually, an application
      is defined within a <span class="code">module</span>, and all global datatypes are defined
      on the top-level. To begin with we create a module and the interfaces we
      need:</p>
    <div class="example"><pre>
// DB IDL
#ifndef _DB_IDL_
#define _DB_IDL_
// A module is simply a container
module DB {

  // An interface maps to a CORBA::Object.
  interface CommonUser {

  };

  // Inherit the Consumer interface
  interface Administrator : CommonUser {

  };

  interface Access {

  };

};
#endif    </pre></div>
    <p>Since the <span class="code">Administrator</span> should be able to do the same things as the
      <span class="code">CommonUser</span>, the previous inherits from the latter. The <span class="code">Access</span>
      interface will grant access to the DB.
      Now we are ready to define the functionality and data types we need. But, this
      requires that we know a little bit more about the OMG IDL.</p>
    <div class="note">
<div class="label">Note</div>
<div class="content"><p>
      <p>The OMG defines a set of reserved case insensitive key-words, which may
        <strong>NOT</strong> be used as identifiers (e.g. module name). For more
        information, see
        <span class="bold_code"><a href="#key_words">Reserved Compiler Names and Keywords</a></span></p>
    </p></div>
</div>
  

  <h3><a name="id76929">6.4 
        Basic OMG IDL Types</a></h3>
    
    <p>The OMG IDL mapping is strongly typed and, even if you have a good knowledge
      of CORBA types, it is essential to read carefully the following mapping to
      Erlang types.</p>
    <p>The mapping of basic types is straightforward. Note that the
      OMG IDL double type is mapped to an Erlang float which does not
      support the full double value range.</p>
    <table border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle">OMG IDL type</td>
        <td align="left" valign="middle">Erlang type</td>
        <td align="left" valign="middle">Note</td>
      </tr>
<tr>
        <td align="left" valign="middle">float</td>
        <td align="left" valign="middle">Erlang float</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">double</td>
        <td align="left" valign="middle">Erlang float</td>
        <td align="left" valign="middle">value range not supported</td>
      </tr>
<tr>
        <td align="left" valign="middle">short</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">-2^15 .. 2^15-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">unsigned short</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">0 .. 2^16-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">long</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">-2^31 .. 2^31-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">unsigned long</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">0 .. 2^32-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">long long</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">-2^63 .. 2^63-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">unsigned long long</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">0 .. 2^64-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">char</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">ISO-8859-1</td>
      </tr>
<tr>
        <td align="left" valign="middle">wchar</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle">UTF-16 (ISO-10646-1:1993)</td>
      </tr>
<tr>
        <td align="left" valign="middle">boolean</td>
        <td align="left" valign="middle">Erlang atom</td>
        <td align="left" valign="middle">true/false</td>
      </tr>
<tr>
        <td align="left" valign="middle">octet</td>
        <td align="left" valign="middle">Erlang integer</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">any</td>
        <td align="left" valign="middle">Erlang record</td>
        <td align="left" valign="middle">#any{typecode, value}</td>
      </tr>
<tr>
        <td align="left" valign="middle">long double</td>
        <td align="left" valign="middle">Not supported</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">Object</td>
        <td align="left" valign="middle">Orber object reference</td>
        <td align="left" valign="middle">Internal Representation</td>
      </tr>
<tr>
        <td align="left" valign="middle">void</td>
        <td align="left" valign="middle">Erlang atom</td>
        <td align="left" valign="middle">ok</td>
      </tr>
</table>
<em>Table
        6.1:
         
        OMG IDL basic types</em>
    <p>The <span class="code">any</span> value is written as a record with the field typecode which
      contains the Type Coderepresentation,
      <span class="bold_code"><a href="#tk_values">see also the Type Code table</a></span>,
      and the value field itself.</p>
    <p>Functions with return type <span class="code">void</span> will return the atom <span class="code">ok</span>.</p>
  

  <h3><a name="id77470">6.5 
        Template OMG IDL Types and Complex Declarators</a></h3>
    
    <p>Constructed types all have native mappings as shown in the table
      below.</p>
    <table border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle"><strong>Type</strong></td>
        <td align="left" valign="middle"><strong>IDL code</strong></td>
        <td align="left" valign="middle"><strong>Maps to</strong></td>
        <td align="left" valign="middle"><strong>Erlang code</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>string</strong></td>
        <td align="left" valign="middle">typedef string S;        <br>
void op(in S a);</td>
        <td align="left" valign="middle">Erlang string</td>
        <td align="left" valign="middle">ok = op(Obj, "Hello World"),</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>wstring</strong></td>
        <td align="left" valign="middle">typedef wstring S;        <br>
void op(in S a);</td>
        <td align="left" valign="middle">Erlang list of Integers</td>
        <td align="left" valign="middle">ok = op(Obj, "Hello World"),</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>sequence</strong></td>
        <td align="left" valign="middle">typedef sequence &lt;long, 3&gt; S;        <br>
void op(in S a);</td>
        <td align="left" valign="middle">Erlang list</td>
        <td align="left" valign="middle">ok = op(Obj, [1, 2, 3]),</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>array</strong></td>
        <td align="left" valign="middle">typedef string S[2];        <br>
void op(in S a);</td>
        <td align="left" valign="middle">Erlang tuple</td>
        <td align="left" valign="middle">ok = op(Obj, {"one", "two"}),</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>fixed</strong></td>
        <td align="left" valign="middle">typedef fixed&lt;3,2&gt; myFixed;        <br>
void op(in myFixed a);</td>
        <td align="left" valign="middle">Erlang tuple</td>
        <td align="left" valign="middle">MF = fixed:create(3, 2, 314),        <br>
ok = op(Obj, MF),</td>
      </tr>
</table>
<em>Table
        6.2:
         
        OMG IDL Template and Complex Declarators</em>

    <h4>String/WString Data Types</h4>
      
      <p>A <span class="code">string</span> consists of all possible 8-bit quantities except null.
        Most ORB:s uses, including Orber, the character set Latin-1 (ISO-8859-1).
        The <span class="code">wstring</span> type is represented as a list of integers, where
        each integer represents a wide character. In this case Orber uses, as
        most other ORB:s, the UTF-16 (ISO-10646-1:1993) character set.</p>
      <p>When defining a a string or wstring they can be of limited length or
        null terminated:</p>
      <div class="example"><pre>
// Null terminated
typedef string myString;
typedef wstring myWString;
// Maximum length 10 
typedef string&lt;10&gt; myString10;
typedef wstring&lt;10&gt; myWString10;
      </pre></div>
      <p>If we want to define a char/string or wchar/wstring constant, we can
        use octal (\OOO - one, two or three octal digits), 
        hexadecimal (\xHH - one or two hexadecimal digits) and unicode (\uHHHH -
        one, two, three or four hexadecimal digits.) representation as well.
        For example:</p>
      <div class="example"><pre>
const string  SwedensBestSoccerTeam = "\101" "\x49" "\u004B";
const wstring SwedensBestHockeyTeam = L"\101\x49\u004B";
const char  aChar  = '\u004B';  
const wchar aWchar = L'\u004C';
      </pre></div>
      <p>Naturally, we can use <span class="code">"Erlang"</span>, <span class="code">L"Rocks"</span>, <span class="code">'A'</span>
        and <span class="code">L'A'</span> as well.</p>
    

    <h4>Sequence Data Type</h4>
      
      <p>A sequence can be defined to be of a maximum length or unbounded, and may 
        contain Basic and Template types and scoped names:</p>
      <div class="example"><pre>
typedef sequence &lt;short, 1&gt; aShortSequence;
typedef sequence &lt;long&gt; aLongSequence;
typedef sequence &lt;aLongSequence&gt; anEvenLongerSequence;
      </pre></div>
    

    <h4>Array Data Type</h4>
      
      <p>Arrays are multidimensional, fixed-size arrays. The indices is language
        mapping specific, which is why one should not pass them as arguments
        to another ORB.</p>
      <div class="example"><pre>
typedef long myMatrix[2][3];
      </pre></div>
    

    <h4>Fixed Data Type</h4>
      
      <p>A Fixed Point literal consists of an integer part (decimal digits), 
        decimal point and a fraction part (decimal digits),
        followed by a <span class="code">D</span> or <span class="code">d</span>. Either the integer part or the
        fraction part may be missing; the decimal point may be missing, 
        but not d/D. The integer part must be a positive integer less than 32.
        The Fraction part must be a positive integer less than or equal to
        the Integer part.</p>
      <div class="example"><pre>
const fixed myFixed1 = 3.14D;
const fixed myFixed2 = .14D;
const fixed myFixed3 = 0.14D;
const fixed myFixed4 = 3.D;
const fixed myFixed5 = 3D;
      </pre></div>
      <p>It is also possible to use unary (+-) and binary (+-*/) operators:</p>
      <div class="example"><pre>
const fixed myFixed6 = 3D + 0.14D;
const fixed myFixed7 = -3.14D;
      </pre></div>
      <p>The Fixed Point examples above are, so called, <strong>anonymous</strong> 
        definitions. In later CORBA specifications these have been deprecated
        as function parameters or return values. Hence, we strongly recommend that
        you do not use them. Instead, you should use:</p>
      <div class="example"><pre>
typedef fixed&lt;5,3&gt; myFixed53;
const myFixed53 myFixed53constant = 03.140d;
typedef fixed&lt;3,2&gt; myFixed32;
const myFixed32 myFixed32constant = 3.14d;

myFixed53 foo(in myFixed32 MF); // OK
void bar(in fixed&lt;5,3&gt; MF); // Illegal
      </pre></div>
    
    <p>For more information, see <span class="bold_code"><a href="fixed.html">Fixed</a></span> in 
      Orber's Reference Manual.</p>
    <p>Now we continue to work on our IDL specification. To begin with, we want
      to limit the size of the logon parameters (Id and password). Since the
      <span class="code">UserID</span> and <span class="code">Password</span> parameters, only will be used when
      invoking operations on the <span class="code">Access</span> interface, we may choose to define
      them within the scope that interface. To keep it simple our DB will contain
      employee information. Hence, as the DB key we choose an integer
      (<span class="code">EmployeeNo</span>).</p>
    <div class="example"><pre>
// DB IDL
#ifndef _DB_IDL_
#define _DB_IDL_
module DB {

  typedef unsigned long EmployeeNo;

  interface CommonUser {

     any lookup(in EmployeeNo ENo);

  };

  interface Administrator : CommonUser {

     void delete(in EmployeeNo ENo);

  };

  interface Access {

      typedef string&lt;10&gt; UserID;
      typedef string&lt;10&gt; Password;

      CommonUser logon(in UserID ID, in Password PW);

  };

};
#endif    </pre></div>
    <p>But what should, for example, the <span class="code">lookup</span> operation return? One option
      is to use the <span class="code">any</span> data type. But, depending on what kind of data it
      encapsulates, this datatype can be rather expensive to use. We might find a 
      solution to our problems among the <span class="code">Constructed</span> IDL types.</p>
  

  <h3><a name="id77956">6.6 
        Constructed OMG IDL Types</a></h3>
    
    <p>Constructed types all have native mappings as shown in the table
      below.</p>
    <table border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle"><strong>Type</strong></td>
        <td align="left" valign="middle"><strong>IDL code</strong></td>
        <td align="left" valign="middle"><strong>Maps to</strong></td>
        <td align="left" valign="middle"><strong>Erlang code</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>struct</strong></td>
        <td align="left" valign="middle">struct myStruct {        <br>
long a;         <br>
short b;        <br>
};        <br>
void op(in myStruct a);</td>
        <td align="left" valign="middle">Erlang record</td>
        <td align="left" valign="middle">ok = op(Obj, #'myStruct'{a=300, b=127}),</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>union</strong></td>
        <td align="left" valign="middle">union myUnion switch(long) {        <br>
case 1: long a;        <br>
};        <br>
void op(in myUnion a);</td>
        <td align="left" valign="middle">Erlang record</td>
        <td align="left" valign="middle">ok = op(Obj, #'myUnion'{label=1, value=66}),</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>enum</strong></td>
        <td align="left" valign="middle">enum myEnum {one, two};        <br>
void op(in myEnum a);</td>
        <td align="left" valign="middle">Erlang atom</td>
        <td align="left" valign="middle">ok = op(Obj, one),</td>
      </tr>
</table>
<em>Table
        6.3:
         
        OMG IDL constructed types</em>

    <h4>Struct Data Type</h4>
      
      <p>A <span class="code">struct</span> may have Basic, Template, Scoped Names and Constructed 
        types as members. By using forward declaration we can define a recursive struct:</p>
      <div class="example"><pre>
struct myStruct; // Forward declaration
typedef sequence&lt;myStruct&gt; myStructSeq;
struct myStruct {
    myStructSeq chain;
};

// Deprecated definition (anonymous) not supported by IC
struct myStruct {
    sequence&lt;myStruct&gt; chain;
};
      </pre></div>
    

    <h4>Enum Data Type</h4>
      
      <p>The maximum number of identifiers which may defined in an enumeration
        is 2³². The order in which the identifiers are named in the
        specification of an enumeration defines the relative order of the
        identifiers.</p>
    

    <h4>Union Data Type</h4>
      
      <p>A <span class="code">union</span> may consist of:</p>
      <ul>
        <li>Identifier</li>
        <li>Switch - may be an integer, char, boolean, enum or scoped name.</li>
        <li>Body - with or without a <span class="code">default</span> case; may appear at 
         most once.</li>
      </ul>
      <p>A case label must match the defined type of the discriminator, and may only
        contain a default case if the values given in the non-default labels do
        not cover the entire range of the union's discriminant type. For example:</p>
      <div class="example"><pre>
// Illegal default; all cases covered by 
// non-default cases.
union BooleanUnion switch(boolean) {
  case TRUE:  long TrueValue;
  case FALSE: long FalseValue;
  default: long DefaultValue; 
};
// OK
union BooleanUnion2 switch(boolean) {
  case TRUE:  long TrueValue;
  default: long DefaultValue; 
};
      </pre></div>
      <p>It is not necessary to list all possible values of the union discriminator
        in the body. Hence, the value of a union is the value of the discriminator
        and, in given order, one of the following:</p>
      <ul>
        <li>If the discriminator match a label, explicitly listed in a 
         case statement, the value must be of the same type.</li>
        <li>If the union contains a default label, the value must match the
         type of the default label.</li>
        <li>No value. Orber then inserts the Erlang atom <span class="code">undefined</span>
         in the value field when receiving a union from an external 
         ORB.</li>
      </ul>
      <p>The above can be summed up to:</p>
      <div class="example"><pre>
// If the discriminator equals 1 or 2 the value 
// is a long. Otherwise, the atom undefined.
union LongUnion switch(long) {
  case 1:
  case 2:  long TrueValue;
};
// If the discriminator equals 1 or 2 the value 
// is a long. Otherwise, a boolean.
union LongUnion2 switch(long) {
  case 1:
  case 2:  long TrueValue;
  default: boolean DefaultValue; 
};
      </pre></div>
      <p>In the same way as structs, unions can be recursive if forward
         declaration is used (anonymous types is deprecated and not supported):</p>
      <div class="example"><pre>
// Forward declaration
union myUnion;
typedef sequence&lt;myUnion&gt;myUnionSeq;
union myUnion switch (long) {
    case 1 : myUnionSeq chain;
    default: boolean DefaultValue;
};
      </pre></div>

    <div class="note">
<div class="label">Note</div>
<div class="content"><p>
      <p>Recursive types (union and struct) require Light IFR. I.e. the
         IC option {light_ifr, true} is used and that Orber is configured in such a way that
         Light IFR is activated. Recursive TypeCode is currently not supported, which is
         why these cannot be encapsulated in an any data type.</p>
    </p></div>
</div>

    
    <div class="warning">
<div class="label">Warning</div>
<div class="content"><p>
      <p>Every field in, for example, a struct must be initiated. Otherwise
        it will be set to the atom <span class="code">undefined</span>, which Orber cannot
        encode when communicating via IIOP. In the example above, invoking
        the operation with #'myStruct'{a=300} will fail (equal to 
        #'myStruct'{a=300, b=undefined})</p>
    </p></div>
</div>
    <p>Now we can continue to work on our IDL specification. To begin with, we should
      determine the return value of the <span class="code">lookup</span> operation. Since the <span class="code">any</span>
      type can be rather expensive we can use a <span class="code">struct</span> or a <span class="code">union</span> instead.
      If we intend to return the same information about a employee every time we can
      use a struct. Let us assume that the DB contains the name, address, employee 
      number and department.</p>
    <div class="example"><pre>
// DB IDL
#ifndef _DB_IDL_
#define _DB_IDL_
module DB {

  typedef unsigned long EmployeeNo;

  enum Department {Department1, Department2};

  struct employee {
        EmployeeNo No;
        string Name; 
        string Address; 
        Department Dpt;
  };

  typedef employee EmployeeData;

  interface CommonUser {

     EmployeeData lookup(in EmployeeNo ENo);

  };

  interface Administrator : CommonUser {

     void delete(in EmployeeNo ENo);

  };

  interface Access {

      typedef string&lt;10&gt; UserID;
      typedef string&lt;10&gt; Password;

      // Since Administrator inherits from CommonUser
      // the returned Object can be of either type.
      CommonUser logon(in UserID ID, in Password PW);

  };

};
#endif    </pre></div>
    <p>We can also define exceptions (i.e. not system exception) thrown by
      each interface. Since exceptions are thoroughly described in the chapter
      <span class="bold_code"><a href="ch_exceptions.html">System and User Defined Exceptions</a></span>,
      we choose not to. Hence, we are now ready to compile our IDL-file by 
      invoking:</p>
    <div class="example"><pre>
$ <span class="bold_code">erlc DB.idl</span>
    </pre></div>
    <p>or:</p>
    <div class="example"><pre>
$ <span class="bold_code">erl</span>
Erlang (BEAM) emulator version 5.1.1 [threads:0]

Eshell V5.1.1  (abort with ^G)
1&gt; <span class="bold_code">ic:gen('DB').</span>
ok
2&gt; <span class="bold_code">halt().</span>
    </pre></div>
    <p>The next step is to implement our servers. But, to be able to do that,
      we need to know how we can access data type definitions. For example,
      since a struct is mapped to an Erlang record we must include an hrl-file
      in our callback module.</p>
  

  <h3><a name="id78395">6.7 
        Scoped Names and Generated Files</a></h3>
    

    <h4>Scoped Names</h4>
      
      <p>Within a scope all identifiers must be unique. The following kinds of
        definitions form scopes in the OMG IDL:</p>
      <ul>
        <li><strong>module</strong></li>
        <li><strong>interface</strong></li>
        <li><strong>operation</strong></li>
        <li><strong>valuetype</strong></li>
        <li><strong>struct</strong></li>
        <li><strong>union</strong></li>
        <li><strong>exception</strong></li>
      </ul>
      <p>For example, since enumerants do not form a scope, the following IDL code
        is not valid:</p>
      <div class="example"><pre>
module MyModule {
     // 'two' is not unique
     enum MyEnum {one, two};
     enum MyOtherEnum {two, three};
};
      </pre></div>
      <p>But, since Erlang only has two levels of scope, <strong>module</strong> and 
        <strong>function</strong>, the OMG IDL scope is mapped as follows:</p>
      <ul>
        <li>
<strong>Function Scope</strong> - used for constants, operations and attributes.</li>
        <li>
<strong>Erlang Module Scope</strong> - the Erlang module scope
         handles the remaining OMG IDL scopes.</li>
      </ul>
      <p>An Erlang module, corresponding to an IDL global name, is derived by 
        converting occurrences of "::" to underscore, and eliminating
        the leading "::". Hence, accessing <span class="code">MyEnum</span> from another module, one 
        use <span class="code">MyModule::MyEnum</span></p>
      <p>For example, an operation <span class="code">foo</span> defined in interface <span class="code">I</span>, which
        is defined in module <span class="code">M</span>, would be written in IDL as <span class="code">M::I::foo</span>
        and as <span class="code">'M_I':foo</span> in Erlang - <span class="code">foo</span> is the function
        name and <span class="code">'M_I'</span> is the name of the Erlang module. Applying this
        knowledge to a stripped version of the DB.idl gives:</p>
      <div class="example"><pre>
// DB IDL
#ifndef _DB_IDL_
#define _DB_IDL_
// ++ topmost scope ++ 
// IC generates oe_XX.erl and oe_XX.hrl.
// XX is equal to the name of the IDL-file.
// Tips: create one IDL-file for each top module
// and give the file the same name (DB.idl).
// The oe_XX.erl module is used to register data
// in the IFR.
module DB {

  // ++ Module scope ++
  // To access 'EmployeeNo' from another scope, use:
  // DB::EmployeeNo, DB::Access etc.
  typedef unsigned long EmployeeNo;

  enum Department {Department1, Department2};

  // Definitions of this struct is contained in:
  // DB.hrl
  // Access functions exported by:
  // DB_employee.erl
  struct employee {
     ... CUT ...
  };

  typedef employee EmployeeData;

  ... CUT ...

  // If this interface should inherit an interface
  // in another module (e.g. OtherModule) use:
  // interface Access : OtherModule::OtherInterface
  interface Access {

      // ++ interface scope ++
      // Types within this scope is accessible via:
      // DB::Access::UserID
      // The Stub/Skeleton for this interface is
      // placed in the module:
      // DB_Access.erl
      typedef string&lt;10&gt; UserID;
      typedef string&lt;10&gt; Password;

      // Since Administrator inherits from CommonUser
      // the returned Object can be of either type.
      // This operation is exported from:
      // DB_Access.erl
      CommonUser logon(in UserID ID, in Password PW);

  };

};
#endif      </pre></div>
      <p>Using underscores in IDL names can lead to ambiguities
        due to the name mapping described above. It is advisable to 
        avoid the use of underscores in identifiers. For example, the following
        definition would generate two structures named <span class="code">x_y_z</span>.</p>
      <div class="example"><pre>
module x {

    struct y_z {
    ...
    };

    interface y {

    struct z {
        ...
    };
    };
};
      </pre></div>
    

    <h4>Generated Files</h4>
      
      <p>Several files can be generated for each scope.</p>
      <ul>
        <li>An Erlang source code file (<span class="code">.erl</span>) is generated
         for top level scope as well as the Erlang header file.</li>
        <li>An Erlang header file (<span class="code">.hrl</span>) will be generated for 
         each scope. The header file will contain record definitions 
         for all <span class="code">struct</span>, <span class="code">union</span> and <span class="code">exception</span> 
         types in that scope.</li>
        <li>Modules that contain at least one constant definition,
         will produce Erlang source code files (<span class="code">.erl</span>).
         That Erlang file will contain constant functions for 
         that scope.
         Modules that contain no constant definitions are considered
         empty and no code will be produced for them, but only for
         their included modules/interfaces.</li>
        <li>Interfaces will produce Erlang source code files (<span class="code">.erl</span>),
         this code will contain all operation stub code and implementation
         functions.</li>
        <li>In addition to the scope-related files, an Erlang source file will
         be generated for each definition of the types <span class="code">struct</span>,
        <span class="code">union</span> and <span class="code">exception</span> (these are the types that
         will be represented in Erlang as records).
         This file will contain special access functions for that record.</li>
        <li>The top level scope will produce two files, one header file
         (<span class="code">.hrl</span>) and one Erlang source file (<span class="code">.erl</span>).
         These files are named as the IDL file, prefixed with <span class="code">oe_</span>.</li>
      </ul>
      <p>After compiling DB.idl, the following files have been generated:</p>
      <ul>
        <li>
<span class="code">oe_DB.hrl</span> and <span class="code">oe_DB.erl</span> for the top scope level.</li>
        <li>
<span class="code">DB.hrl</span> for the module <span class="code">DB</span>.</li>
        <li>
<span class="code">DB_Access.hrl</span> and <span class="code">DB_Access.erl</span> for the interface 
        <span class="code">DB_Access</span>.</li>
        <li>
<span class="code">DB_CommonUser.hrl</span> and <span class="code">DB_CommonUser.erl</span> for the interface 
        <span class="code">DB_CommonUser</span>.</li>
        <li>
<span class="code">DB_Administrator.hrl</span> and <span class="code">DB_Administrator.erl</span> for the interface 
        <span class="code">DB_Administrator</span>.</li>
        <li>
<span class="code">DB_employee.erl</span> for the structure <span class="code">employee</span> in module 
        <span class="code">DB</span>.</li>
      </ul>
      <p>Since the <span class="code">employee</span> struct is defined in the top level scope,
        the Erlang record definition is found in <span class="code">DB.hrl</span>. IC also generates
        stubs/skeletons (e.g. <span class="code">DB_CommonUser.erl</span>) and access functions for
        some datatypes (e.g. <span class="code">DB_employee.erl</span>). How the stubs/skeletons are
        used is thoroughly described in
        <span class="bold_code"><a href="ch_stubs.html">Stubs/Skeletons</a></span> and
        <span class="bold_code"><a href="Module_Interface.html">Module_Interface</a></span>.</p>
    
  

  <h3><a name="id78787">6.8 
        Typecode, Identity and Name Access Functions</a></h3>
    
    <p>As mentioned in a previous section, <span class="code">struct</span>, <span class="code">union</span> and 
      <span class="code">exception</span> types yield record definitions and access code 
      for that record. 
      For <span class="code">struct</span>, <span class="code">union</span>, <span class="code">exception</span>, <span class="code">array</span> and 
      <span class="code">sequence</span> types, a special file is generated that holds access
      functions for <span class="code">TypeCode</span>, <span class="code">Identity</span> and <span class="code">Name</span>.
      These functions are put in the file corresponding to the scope where 
      they are defined. For example, the module <span class="code">DB_employee.erl</span>, 
      representing the <span class="code">employee</span> struct, exports the following functions:</p>
    <ul>
      <li>tc/0 - returns the type code for the struct.</li>
      <li>id/0 - returns the IFR identity of the struct. In this case
       the returned value is <span class="code">"IDL:DB/employee:1.0"</span>, but
       if the struct was defined in the scope of <span class="code">CommonUser</span>,
       the result would be <span class="code">"IDL:DB/CommonUser/employee:1.0"</span>.
       However, the user usually do not need to know the Id, just
       which Erlang module contains the correct Id.</li>
      <li>name/0 - returns the scoped name of the struct. The <span class="code">employee</span>
       struct name is <span class="code">"DB_employee"</span>.</li>
    </ul>
    <p>Type Codesare, for example, used in <span class="bold_code"><a href="any.html">Any</a></span> values.
      Hence, we can encapsulate the <span class="code">employee</span> struct in an <span class="code">any</span>
      type by:</p>
    <div class="example"><pre>
%% Erlang code
....
AnEmployee = #'DB_employee'{'No'      = 1,
                            'Name'    = "Adam Ivan Kendall",
                            'Address' = "Rasunda, Solna",
                            'Dpt'     = 'Department1'},
EmployeeTC = 'DB_employee':tc(),
EmployeeAny = any:create(EmployeeTC, AnEmployee),
....
    </pre></div>
    <p>For more information, see the
      <span class="bold_code"><a href="#tk_values">Type Code listing</a></span>.</p>
  

  <h3><a name="id78931">6.9 
        References to Constants</a></h3>
    
    <p>Constants are generated as Erlang functions, and are accessed by a
      single function call. The functions are put in the file
      corresponding to the scope where they are defined. There is no
      need for an object to be started to access a constant.</p>
    <p>Example:</p>
    <div class="example"><pre>
// m.idl
module m {
    const float pi = 3.14;

    interface i {
    const float pi = 3.1415;
    };
};
    </pre></div>
    <p>Since the two constants are defined in different scopes, the IDL code
      above is valid, but not necessarily a good approach. After compiling
      <span class="code">m.idl</span>, the constant definitions can be extracted by invoking:</p>
    <div class="example"><pre>
$ <span class="bold_code">erlc m.idl</span>
$ <span class="bold_code">erlc m.erl</span>
$ <span class="bold_code">erl</span>
Erlang (BEAM) emulator version 5.1.1 [threads:0]

Eshell V5.1.1  (abort with ^G)
1&gt; <span class="bold_code">m:pi().</span>
3.14
2&gt; <span class="bold_code">m_i:pi().</span>
3.1415
3&gt; <span class="bold_code">halt().</span>
    </pre></div>
  

  <h3><a name="id78990">6.10 
        References to Objects Defined in OMG IDL</a></h3>
    
    <p>Objects are accessed by object references. An object reference
      is an opaque Erlang term created and maintained by the ORB.</p>
    <p>Objects are implemented by providing implementations for all
      operations and attributes of the Object, <span class="bold_code"><a href="#op_impl">see operation implementation</a></span>.</p>
  

  <h3><a name="id79013">6.11 
        Exceptions</a></h3>
    
    <p>Exceptions are handled as Erlang catch and throws. Exceptions
      are translated to messages over an IIOP bridge but converted
      back to a throw on the receiving side. Object implementations
      that invoke operations on other objects must be aware of the
      possibility of a non-local return. This includes invocation of
      ORB and IFR services. See also the
      <span class="bold_code"><a href="ch_exceptions.html">Exceptions</a></span> section.</p>
    <p>Exception parameters are mapped as an Erlang record and accessed
      as such.</p>
    <p>An object implementation that raises an exception will use the
      <span class="code">corba:raise/1</span> function, passing the exception record as
      parameter.</p>
  

  <h3><a name="id79046">6.12 
        Access to Attributes</a></h3>
    
    <p>Attributes are accessed through their access functions. An
      attribute implicitly defines the <span class="code">_get</span> and <span class="code">_set</span>
      operations. These operations are handled in the same way as
      normal operations. The <span class="code">_get</span> operation is defined as a <span class="code">readonly</span> 
      attribute.</p>
    <div class="example"><pre>
readonly attribute long RAttribute;
attribute long RWAttribute;
    </pre></div>
    <p>The <span class="code">RAttribute</span> requires that you implement, in your call-back module,
      <span class="code">_get_RAttribute</span>. For the <span class="code">RWAttribute</span> it is necessary to implement
      <span class="code">_get_RWAttribute</span> and <span class="code">_set_RWAttribute</span>.</p>
  

  <h3><a name="id79103">6.13 
        Invocations of Operations</a></h3>
    
    <a name="op_impl"></a>
    <p>A standard Erlang <span class="code">gen_server</span> behavior is used for
      object implementation. The <span class="code">gen_server</span> state is then
      used as the object internal state. Implementation of the object 
      function is achieved by implementing its methods and attribute operations.
      These functions will usually have the internal state as their first parameter, 
      followed by any <span class="code">in</span> and <span class="code">inout</span> parameters. </p>
    <p>Do not confuse the
      object internal state with its object reference. The object internal state is
      an Erlang term which has a format defined by the user.</p>
    <div class="note">
<div class="label">Note</div>
<div class="content"><p>
      <p>It 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>
    </p></div>
</div>
    <p>A function call will invoke an operation. The first
      parameter of the function should be the object reference and then
      all <span class="code">in</span> and <span class="code">inout</span> parameters follow in the same
      order as specified in the IDL specification. The result will be a return value
      unless the function has <span class="code">inout</span> or <span class="code">out</span> parameters specified; 
      in which case, a tuple of the return value, followed by the parameters will
      be returned.</p>
    <p>Example:</p>
    <div class="example"><pre>
// IDL
module m {
  interface i {
      readonly attribute long RAttribute;
      attribute long RWAttribute;
      long foo(in short a);
      long bar(in char c, inout string s, out long count);
      void baz(out long Id);
  };
};
    </pre></div>
    <p>Is used in Erlang as :</p>
    <div class="example"><pre>
%% Erlang code
....
Obj = ...    %% get object reference
RAttr  = m_i:'_get_RAttribute'(Obj),
RWAttr = m_i:'_get_RWAttribute'(Obj),
ok = m_i:'_set_RWAttribute'(Obj, Long),
R1 = m_i:foo(Obj, 55),
{R2, S, Count} = m_i:bar(Obj, $a, "hello"),
....
    </pre></div>
    <p>Note how the <span class="code">inout</span> parameter is passed <strong>and</strong>
      returned. There is no way to use a single occurrence of a
      variable for this in Erlang. Also note, that <span class="code">ok</span>, Orber's 
      representation of the IDL-type <span class="code">void</span>, must be returned by
      <span class="code">baz</span> and <span class="code">'_set_RWAttribute'</span>. 
      These operations can be implemented in the call-back module as:</p>
    <div class="example"><pre>
'_set_RWAttribute'(State, Long) -&gt;
    {reply, ok, State}.

'_get_RWAttribute'(State) -&gt;
    {reply, Long, State}.

'_get_RAttribute'(State) -&gt;
    {reply, Long, State}.

foo(State, AShort) -&gt;
    {reply, ALong, State}.
 
bar(State, AShort, AString) -&gt;
    {reply, {ALong, "MyString", ALong}, State}.
 
baz(State) -&gt;
    {reply, {ok, AId}, State}.
    </pre></div>
    <p>The operations may require more arguments (depends on IC options used). For
      more information, see <span class="bold_code"><a href="ch_stubs.html">Stubs/Skeletons</a></span>
      and <span class="bold_code"><a href="Module_Interface.html">Module_Interface</a></span>.</p>
    <div class="warning">
<div class="label">Warning</div>
<div class="content"><p>
      <p>A function can also be defined to be <span class="code">oneway</span>, i.e. 
        asynchronous. But, since the behavior of a oneway operation is not
        defined in the OMG specifications (i.e. the behavior can differ depending on
        which other ORB Orber is communicating with), one should avoid using it.</p>
    </p></div>
</div>
  

  <h3><a name="id79262">6.14 
        Implementing the DB Application</a></h3>
    
    <p>Now we are ready to implement the call-back modules. There are three modules
      we must create:</p>
    <ul>
      <li>DB_Access_impl.erl</li>
      <li>DB_CommonUser_impl.erl</li>
      <li>DB_Administrator_impl.erl</li>
    </ul>
    <p>An easy way to accomplish that, is to use the IC backend <span class="code">erl_template</span>,
      which will generate a complete call-back module. One should also add
      the same compile options, for example <span class="code">this</span> or <span class="code">from</span>,
      used when generating the stub/skeleton modules:</p>
    <div class="example"><pre>
$&gt; erlc +"{be,erl_template}" DB.idl
    </pre></div>
    <p>We begin with implementing the <span class="code">DB_Access_impl.erl</span> module, which,
      if we used <span class="code">erl_template</span>, will look like the following. All we need
      to do is to add the logic to the <span class="code">logon</span> operation.</p>
    <div class="example"><pre>
%%----------------------------------------------------------------------
%% &lt;LICENSE&gt;
%% 
%%     $Id$
%%
%%----------------------------------------------------------------------
%% Module       : DB_Access_impl.erl
%% 
%% Source       : /home/user/example/DB.idl
%% 
%% Description  : 
%% 
%% Creation date: 2005-05-20
%%
%%----------------------------------------------------------------------
-module('DB_Access_impl').

-export([logon/3]).

%%----------------------------------------------------------------------
%% Internal Exports
%%----------------------------------------------------------------------
-export([init/1,
         terminate/2,
         code_change/3,
         handle_info/2]).

%%----------------------------------------------------------------------
%% Include Files
%%----------------------------------------------------------------------


%%----------------------------------------------------------------------
%% Macros
%%----------------------------------------------------------------------


%%----------------------------------------------------------------------
%% Records
%%----------------------------------------------------------------------
-record(state, {}).

%%======================================================================
%% API Functions
%%======================================================================
%%----------------------------------------------------------------------
%% Function   : logon/3
%% Arguments  : State - term()
%%              ID = String()
%%              PW = String()
%% Returns    : ReturnValue = OE_Reply
%%              OE_Reply = Object_Ref()
%% Raises     : 
%% Description: 
%%----------------------------------------------------------------------
logon(State, ID, PW) -&gt;
    %% Check if the ID/PW is valid and what 
    %% type of user it is (Common or Administrator).
    OE_Reply
            = case check_user(ID, PW) of
             {ok, administrator} -&gt;
                'DB_Administrator':oe_create();
             {ok, common} -&gt;
                'DB_CommonUser':oe_create();
             error -&gt;
                %% Here we should throw an exception              
                corba:raise(....)
        end,
    {reply, OE_Reply, State}.

%%======================================================================
%% Internal Functions
%%======================================================================
%%----------------------------------------------------------------------
%% Function   : init/1
%% Arguments  : Env = term()
%% Returns    : {ok, State}          |
%%              {ok, State, Timeout} |
%%              ignore               |
%%              {stop, Reason}
%% Raises     : -
%% Description: Initiates the server
%%----------------------------------------------------------------------
init(_Env) -&gt;
    {ok, #state{}}.


%%----------------------------------------------------------------------
%% Function   : terminate/2
%% Arguments  : Reason = normal | shutdown | term()
%%              State = term()
%% Returns    : ok
%% Raises     : -
%% Description: Invoked when the object is terminating.
%%----------------------------------------------------------------------
terminate(_Reason, _State) -&gt;
    ok.


%%----------------------------------------------------------------------
%% Function   : code_change/3
%% Arguments  : OldVsn = undefined | term()
%%              State = NewState = term()
%%              Extra = term()
%% Returns    : {ok, NewState}
%% Raises     : -
%% Description: Invoked when the object should update its internal state
%%              due to code replacement.
%%----------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) -&gt;
    {ok, State}.


%%----------------------------------------------------------------------
%% Function   : handle_info/2
%% Arguments  : Info = normal | shutdown | term()
%%              State = NewState = term()
%% Returns    : {noreply, NewState}          |
%%              {noreply, NewState, Timeout} |
%%              {stop, Reason, NewState}
%% Raises     : -
%% Description: Invoked when, for example, the server traps exits.
%%----------------------------------------------------------------------
handle_info(_Info, State) -&gt;
    {noreply, State}.
    </pre></div>
    <p>Since <span class="code">DB_Administrator</span> inherits from <span class="code">DB_CommonUser</span>,
      we must implement <span class="code">delete</span> in the <span class="code">DB_Administrator_impl.erl</span>
      module, and <span class="code">lookup</span> in <span class="code">DB_Administrator_impl.erl</span><strong>and</strong><span class="code">DB_CommonUser_impl.erl</span>. But wait, is that really necessary? Actually,
      it is not. We simple use the IC compile option <strong>impl</strong>:</p>
    <div class="example"><pre>
$ <span class="bold_code">erlc +'{{impl, "DB::CommonUser"}, "DBUser_impl"}'  +'{{impl, "DB::Administrator"}, "DBUser_impl"}' DB.idl</span>
$ <span class="bold_code">erlc *.erl</span>
    </pre></div>
    <p>Instead of creating, and not the least, maintaining two call-back modules,
      we only have to deal with <span class="code">DBUser_impl.erl</span>. If we generated the
      templates, we simply rename <span class="code">DB_Administrator_impl.erl</span> to
      <span class="code">DBUser_impl.erl</span>. See also the
      <span class="bold_code"><a href="ch_exceptions.html">Exceptions</a></span> chapter.
      In the following example, only the implementation of the API functions
      are shown:</p>
    <div class="example"><pre>
%%======================================================================
%% API Functions
%%======================================================================
%%----------------------------------------------------------------------
%% Function   : delete/2
%% Arguments  : State - term()
%%              ENo = unsigned_Long()
%% Returns    : ReturnValue = ok
%% Raises     : 
%% Description: 
%%----------------------------------------------------------------------
delete(State, ENo) -&gt;
        %% How we access the DB, for example mnesia, is not shown here.
        case delete_employee(No) of
            ok -&gt;
                {reply, ok, State};
            error -&gt;
                %% Here we should throw an exception if
                %% there is no match.
                corba:raise(....)
        end.

%%----------------------------------------------------------------------
%% Function   : lookup/2
%% Arguments  : State - term()
%%              ENo = unsigned_Long()
%% Returns    : ReturnValue = OE_Reply
%%              OE_Reply = #'DB_employee'{No,Name,Address,Dpt}
%%              No = unsigned_Long()
%%              Name = String()
%%              Address = String()
%%              Dpt = Department
%%              Department = 'Department1' | 'Department2' 
%% Raises     : 
%% Description: 
%%----------------------------------------------------------------------
lookup(State, ENo) -&gt;
        %% How we access the DB, for example mnesia, is not shown here.
        case lookup_employee(ENo) of
            %% We assume that we receive a 'DB_employee' struct
            {ok, Employee} -&gt;
                OE_Reply = Employee,
                {reply, OE_Reply, State};
            error -&gt;
                %% Here we should throw an exception if
                %% there is no match.
                corba:raise(....)
        end.
    </pre></div>
    <p>After you have compiled both call-back modules, and implemented the missing
      functionality (e.g. lookup_employee/1), we can test our application:</p>
    <div class="example"><pre>
%% Erlang code
....
%% Create an Access object
Acc = 'DB_Access':oe_create(),

%% Login is Common user and Administrator
Adm = 'DB_Access':logon(A, "admin", "pw"),
Com = 'DB_Access':logon(A, "comm", "pw"),

%% Lookup existing employee
Employee = 'DB_Administrator':lookup(Adm, 1),
Employee = 'DB_CommonUser':lookup(Adm, 1),

%% If we try the same using the DB_CommonUser interface 
%% it result in an exit since that operation is not exported.
{'EXIT', _} = (catch 'DB_CommonUser':delete(Adm, 1)),

%% Try to delete the employee via the CommonUser Object
{'EXCEPTION', _} = (catch 'DB_Administrator':delete(Com, 1)),

%% Invoke delete operation on the Administrator object
ok = 'DB_Administrator':delete(Adm, 1),
....
    </pre></div>
  

  <h3><a name="id79480">6.15 
        Reserved Compiler Names and Keywords</a></h3>
    
    <a name="key_words"></a>
    <p>The use of some names is  strongly discouraged due to 
      ambiguities. However, the use of some names is prohibited 
      when using the Erlang mapping , as they are strictly reserved for IC.</p>
    <p>IC reserves all identifiers starting with <span class="code">OE_</span> and <span class="code">oe_</span> 
      for internal use.</p>
    <p>Note also, that an identifier in IDL can  contain alphabetic,
      digits and underscore characters, but the first character 
      <strong>must</strong> be alphabetic.
      </p>
    <p>The OMG defines a set of reserved words, shown below, for use as keywords. 
      These may <strong>not</strong> be used as, for example, identifiers. The keywords
      which are not in bold face was introduced in the OMG CORBA-3.0 
      specification.</p>
    <table border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle"><strong>abstract</strong></td>
        <td align="left" valign="middle"><strong>exception</strong></td>
        <td align="left" valign="middle"><strong>inout</strong></td>
        <td align="left" valign="middle">provides</td>
        <td align="left" valign="middle"><strong>truncatable</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>any</strong></td>
        <td align="left" valign="middle">emits</td>
        <td align="left" valign="middle"><strong>interface</strong></td>
        <td align="left" valign="middle"><strong>public</strong></td>
        <td align="left" valign="middle"><strong>typedef</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>attribute</strong></td>
        <td align="left" valign="middle"><strong>enum</strong></td>
        <td align="left" valign="middle"><strong>local</strong></td>
        <td align="left" valign="middle">publishes</td>
        <td align="left" valign="middle">typeid</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>boolean</strong></td>
        <td align="left" valign="middle">eventtype</td>
        <td align="left" valign="middle"><strong>long</strong></td>
        <td align="left" valign="middle"><strong>raises</strong></td>
        <td align="left" valign="middle">typeprefix</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>case</strong></td>
        <td align="left" valign="middle"><strong>factory</strong></td>
        <td align="left" valign="middle"><strong>module</strong></td>
        <td align="left" valign="middle"><strong>readonly</strong></td>
        <td align="left" valign="middle"><strong>unsigned</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>char</strong></td>
        <td align="left" valign="middle"><strong>FALSE</strong></td>
        <td align="left" valign="middle">multiple</td>
        <td align="left" valign="middle">setraises</td>
        <td align="left" valign="middle"><strong>union</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle">component</td>
        <td align="left" valign="middle">finder</td>
        <td align="left" valign="middle"><strong>native</strong></td>
        <td align="left" valign="middle"><strong>sequence</strong></td>
        <td align="left" valign="middle">uses</td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>const</strong></td>
        <td align="left" valign="middle"><strong>fixed</strong></td>
        <td align="left" valign="middle"><strong>Object</strong></td>
        <td align="left" valign="middle"><strong>short</strong></td>
        <td align="left" valign="middle"><strong>ValueBase</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle">consumes</td>
        <td align="left" valign="middle"><strong>float</strong></td>
        <td align="left" valign="middle"><strong>octet</strong></td>
        <td align="left" valign="middle"><strong>string</strong></td>
        <td align="left" valign="middle"><strong>valuetype</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>context</strong></td>
        <td align="left" valign="middle">getraises</td>
        <td align="left" valign="middle"><strong>oneway</strong></td>
        <td align="left" valign="middle"><strong>struct</strong></td>
        <td align="left" valign="middle"><strong>void</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>custom</strong></td>
        <td align="left" valign="middle">home</td>
        <td align="left" valign="middle"><strong>out</strong></td>
        <td align="left" valign="middle"><strong>supports</strong></td>
        <td align="left" valign="middle"><strong>wchar</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>default</strong></td>
        <td align="left" valign="middle">import</td>
        <td align="left" valign="middle">primarykey</td>
        <td align="left" valign="middle"><strong>switch</strong></td>
        <td align="left" valign="middle"><strong>wstring</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle"><strong>double</strong></td>
        <td align="left" valign="middle"><strong>in</strong></td>
        <td align="left" valign="middle"><strong>private</strong></td>
        <td align="left" valign="middle"><strong>TRUE</strong></td>
        <td align="left" valign="middle"></td>
      </tr>
</table>
<em>Table
        6.4:
         
        OMG IDL keywords</em>
    <p>The keywords listed above must be written exactly as shown. Any usage
      of identifiers that collide with a keyword is illegal. For example,
      <strong>long</strong> is a valid keyword; <strong>Long</strong> and <strong>LONG</strong> are
      illegal as keywords and identifiers. But, since the OMG must be able
      to expand the IDL grammar, it is possible to use <strong>Escaped  Identifiers</strong>. For example, it is not unlikely that <span class="code">native</span>
      have been used in IDL-specifications as identifiers. One option is to
      change all occurrences to <span class="code">myNative</span>. Usually, it is necessary
      to change programming language code that depends upon that IDL as well.
      Since Escaped Identifiers just disable type checking (i.e. if it is a reserved
      word or not) and leaves everything else unchanged, it is only necessary to
      update the IDL-specification. To escape an identifier, simply prefix it
      with <strong>_</strong>. The following IDL-code is illegal:</p>
    <div class="example"><pre>
typedef string native;
interface i {
   void foo(in native Arg);
   };
};
    </pre></div>
    <p>With Escaped Identifiers the code will look like:</p>
    <div class="example"><pre>
typedef string _native;
interface i {
   void foo(in _native Arg);
   };
};
    </pre></div>
  

  <h3><a name="id80225">6.16 
        Type Code Representation</a></h3>
    
    <a name="tk_values"></a>
    <p>Type Codes are used in <span class="code">any</span> values. To avoid mistakes, you should
      use access functions exported by the Data Types modules
      (e.g. struct, union etc) or the <span class="bold_code"><a href="orber_tc.html">orber_tc</a></span>
      module.</p>
    <table border="1" cellpadding="2" cellspacing="0">
<tr>
        <td align="left" valign="middle"><strong>Type Code</strong></td>
        <td align="left" valign="middle"><strong>Example</strong></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_null</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_void</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_short</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_long</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_longlong</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_ushort</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_ulong</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_ulonglong</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_float</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_double</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_boolean</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_char</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_wchar</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_octet</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_any</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_TypeCode</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">tk_Principal</td>
        <td align="left" valign="middle"></td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_objref, IFRId, Name}</td>
        <td align="left" valign="middle">{tk_objref, "IDL:M1\I1:1.0", "I1"}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_struct, IFRId, Name, [{ElemName, ElemTC}]}</td>
        <td align="left" valign="middle">{tk_struct, "IDL:M1\S1:1.0", "S1", [{"a", tk_long}, {"b", tk_char}]}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_union, IFRId, Name, DiscrTC, DefaultNr, [{Label, ElemName, ElemTC}]}         <br>
Note: DefaultNr tells which of tuples in the case list that is default, or -1 if no default</td>
        <td align="left" valign="middle">{tk_union, "IDL:U1:1.0", "U1", tk_long, 1, [{1, "a", tk_long}, {default, "b", tk_char}]}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_enum, IFRId, Name, [ElemName]}</td>
        <td align="left" valign="middle">{tk_enum, "IDL:E1:1.0", "E1", ["a1", "a2"]}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_string, Length}</td>
        <td align="left" valign="middle">{tk_string, 5}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_wstring, Length}</td>
        <td align="left" valign="middle">{tk_wstring, 7}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_fixed, Digits, Scale}</td>
        <td align="left" valign="middle">{tk_fixed, 3, 2}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_sequence, ElemTC, Length}</td>
        <td align="left" valign="middle">{tk_sequence, tk_long, 4}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_array, ElemTC, Length}</td>
        <td align="left" valign="middle">{tk_array, tk_char, 9}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_alias, IFRId, Name, TC}</td>
        <td align="left" valign="middle">{tk_alias, "IDL:T1:1.0", "T1", tk_short}</td>
      </tr>
<tr>
        <td align="left" valign="middle">{tk_except, IFRId, Name, [{ElemName, ElemTC}]}</td>
        <td align="left" valign="middle">{tk_except, "IDL:Exc1:1.0", "Exc1", [{"a", tk_long}, {"b", {tk_string, 0}}]}</td>
      </tr>
</table>
<em>Table
        6.5:
         
        Type Code tuples</em>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>