.. _Mapping_Ada_to_Java:

*******************
Mapping Ada to Java
*******************

To allow an Ada package to be used from Java,
``ada2java`` generates one or more Java classes
(source files that will need to be compiled to bytecodes by
a Java compiler)
based on the content of the visible part of the Ada package spec.
This section explains and illustrates the mapping for each of the
various kinds of entities declared in a package that can be used
from Java.

In brief:

* 
  Although there are some exceptions to this rule,
  in general a type and certain of its associated subprograms declared
  in an Ada package are mapped to a Java class with methods corresponding to
  the Ada subprograms.  Such entities are said to be *attached* to the
  resulting class.
  
  .. index:: Attachment (of entities to a class)

* 
  Other entities declared in the Ada package map to static members
  defined in a 'default class' generated by ``ada2java``.
  In particular,
  variables and constants in the Ada package map to private static fields
  in the default class and are accessed through ''getter'' (and 'setter'
  for variables) methods.
  Such entities are said to be *unattached*.

  .. index:: Default class

If the default class is generated, its name is that of the
original Ada package (with the same casing as the identifier in the
package declaration) suffixed with ``_Package``.

In the examples, only the portions of the Java classes
needed by users of the classes are shown.

.. _Types:

Types
=====

Types used in the Ada package map to Java types in the generated
class(es). This section explains the correspondence. As a general
rule, note that while most forms of type declarations have a
correspondence in Java, subtype declarations are ignored, as
there is no equivalent to subtypes in Java. However, subtype
constraints imposed on Ada entities, such as variables or
formal parameters, must be respected when referenced from
Java, and can result in exceptions when constraints are violated.

.. _Scalar_Types:

Scalar Types
------------

.. index:: Scalar types (mapping to Java)

The following table shows how Ada scalar types are mapped to
Java primitive types:

+-------------------------+-------------+
| Ada type                | Java type   |
+=========================+=============+
| Integer type <= 32 bits | ``int``     |
+-------------------------+-------------+
| Integer type > 32 bits  | ``long``    |
+-------------------------+-------------+
| ``Boolean``             | ``boolean`` |
+-------------------------+-------------+
| ``Character``           | ``char``    |
+-------------------------+-------------+
| Other enumeration type  | ``int``     |
+-------------------------+-------------+
| Fixed-point type        | ``double``  |
+-------------------------+-------------+
| Floating-point type     | ``double``  |
+-------------------------+-------------+

.. index:: Constraint checks

Constraint checks generated in the Ada glue code detect errors that may
result from the range mismatches between Ada and Java.
For example, since a 16-bit Ada integer will be mapped to 32-bit ``int``
in Java, the Java code might attempt to pass an out-of-range value to Ada.
This will raise a ``Constraint_Error`` exception in Ada, which will be
propagated back to Java as an ``AdaException`` exception.

For an enumeration type, a Java final class is created,
with the same name as the enumeration type.
This class defines the possible values for the
enumeration.

.. index:: Enumeration types (mapping to Java)

Example:


::

  package Pckg is
     type Enum is (A, B, C);
  end Pckg;
   

will give:


::

  package Pckg;

  public final class Enum {
     public static final int A = 0;
     public static final int B = 1;
     public static final int C = 2;
  }
  

Representation clauses for enumeration types are not currently
supported.

A discussion of subprogram formal parameters of scalar types may be found in
:ref:`Subprogram_parameters`.

.. _Arrays:

Arrays
------

.. index:: Array types (mapping to Java)

Mapping Ada arrays to Java arrays would be very expensive, since it
would imply a copy of the whole array each time a parameter has to be passed.
Thus for efficiency an Ada array type is mapped to
a dedicated 'proxy' class with methods that serve as accessors
to attributes and components. For example:


::

  package Ex1 is
     type T1 is array(Integer range <>) of Float;
  end Ex1;
   

will yield the following class:


::

  public final class T1 extends com.adacore.ajis.internal.ada.AdaProxy {
     ...
     public T1 (int First_1, int Last_1){...}

     final public double Get_Element_At (int Index_1){...}

     final public void Set_Element_At (int Index_1, double Value){...}

     final public int First (){...}

     final public int Last (){...}

     final public int Length (){...}
  }
  

A subprogram that takes a parameter of the Ada array type is mapped to
a method taking a parameter of the corresponding Java 'proxy' class;
note that this method is located in the default class, and not in the proxy
class.

.. _Strings:

Strings
-------

.. index:: Strings (mapping to Java)

Directly passing ``String`` data between Ada and Java would require
expensive copying, and thus an alternative approach is used.
The Ada type ``String`` is mapped to the Java class ``AdaString``,
which encapsulates the accesses.

More specifically,
an Ada parameter of type ``String`` of any mode, and an Ada
``access String`` parameter, are both mapped to a Java parameter of type
``AdaString``.

For efficiency, an ``AdaString`` object caches both its Ada and Java
string values after they have been computed.
As an example, if the Ada spec is:


::

  package Pckg is
     procedure P (V : String);
  end Pckg;
  

then the generated Java will be:


::

  public final class Pckg_Package {
     public static void P (V : AdaString) {...}
  }
  

If we now write:


::

  AdaString str = new AdaString ("A string from Java");
  Pckg_Package.P (str);
  Pckg_Package.P (str);
   

Only the first call will require the expensive string translation from
Java to Ada. The second invocation will directly use
the cached value.

Please note that Java strings are UTF16-encoded, whereas the corresponding
Ada strings will be UTF8-encoded. This may have significant impact when
computing character offset on Java strings.

.. index:: UTF-8 encoding

.. index:: UTF-16 encoding

.. _Simple_Record_Types:

Simple Record Types
-------------------

.. index:: Record types (mapping to Java)

Simple (that is, not tagged) record types are mapped to Java final classes.
Components are accessed through a set of generated accessors
('getter' / 'setter' methods). As a current limitation, ``ada2java``
does not yet support accessing discriminant components.

Example:


::

  package Pckg is
     type R is
        record
           F1 : Integer;
           F2 : Float;
        end record;
  end Pckg;
  

will give:


::

  package Pckg;
  public final class R {
     public R () {...}

     public final int F1 () {...}
     public final void F1 (int Value) {...}

     public final double F2 () {...}
     public final void F2 (double Value) {.../}
  }
  

A component that has an access-to-record type is treated as though
it were of the record type itself.  For example:


::

  package Pckg is
     type R is
        record
           F1 : Integer;
           F2 : Float;
        end record;
     type S is
        record
           G1 : R;
           G2 : access R;
        end record;
  end Pckg;
  

will result in both a class ``R`` as above, and the
following class ``S``:


::

  package Pckg;
  public final class S {
     public S () {...}

     public R G1 () {...}
     public void G1 (R Value) {...}

     public R G2 () {...}
     public void G2 (R Value) {...}
  }
  

Only one level of indirection is implemented;
``ada2java`` does not support access to access-to-record.

A private (untagged) type is treated like a record type, except that
it does not have any component-accessing methods. (A later release of
``ada2java`` will generate methods for accessing discriminants
if the type has any.)

.. _Tagged_Types:

Tagged Types
------------

.. index:: Tagged types (mapping to Java)

A tagged type is mapped to a Java class of the same name.
If the Ada type is abstract, then the Java type will be abstract as well.

.. _General_principles:

General principles
^^^^^^^^^^^^^^^^^^

A primitive (i.e., dispatching) subprogram of a tagged type is mapped to
a corresponding Java instance method.
A current restriction is that the first parameter of the Ada subprogram
must be a controlling parameter; otherwise the subprogram is mapped to a
method in the default class.
(Thus a function that delivers a value of the tagged type, but has no
controlling parameter, is mapped to a method in the default class, and
not to a method in the class corresponding to the Ada type.)
The first Ada parameter is mapped to the Java method's implicit ``this``
parameter.

A subprogram with a class-wide parameter is mapped to a method of the
tagged type's Java class whose corresponding parameter has the Java
class type.  However, as this is not properly a dispatching primitive
of the Ada type, it is declared as a final method.

.. index:: Class-wide parameters (mapping to Java)

As an example:


::

  package Ex1 is
     type T is tagged null record;
     procedure P1 (X : in out T; F : Float);
     procedure P2 (X : T'Class);
     procedure Q1 (I : Integer; X : T);
     procedure Q2 (I : Integer; X : T'Class);
     function F return T;
  end Ex1;
  

is mapped to:


::

  public final class Ex1_Package {
     ...
     static public void Q1 (int I, Ex1.T X){...}

     static public void Q2 (int I, Ex1.T X){...}

     static public T F (){...}
  } // Ex1_Package
 
  public class T extends com.adacore.ajis.internal.ada.AdaProxy {
     ...
     public void P1 (double F){...}

     final public void P2 (){...}
  } // T
  

.. _Ada_type_hierarchies:

Ada type hierarchies
^^^^^^^^^^^^^^^^^^^^

Hierarchies of Ada types are preserved in the generated Java classes.
Therefore, the following structure:


::

     type R is tagged record;

     type R_Child is new R with null record;
  

will result in:


::

  public class R {...}

  public class R_Child extends R {...}
  

Consistency of Java types is guaranteed at run time.
For example, the following function:


::

  package Pckg is
     function F return R'Class;
  end Pckg;
  

will result in:


::

  public final class Pckg_Package {
     public R F () {...}
  }
  

However, if the actual type of the returned object is ``R_Child``, then
the value returned by the Java function will be of the Java type
corresponding to ``R_Child``.

.. _Java_class_hierarchies:

Java class hierarchies
^^^^^^^^^^^^^^^^^^^^^^

It is possible to extend a Java class that was generated by ``ada2java``
from an Ada tagged type.

For example:


::

  package Rec_Pckg
     type Rec is tagged null record;
     procedure P (R : Rec);
  end Rec_Pckg;
  

results in a Java class ``Rec`` with an instance method ``P``:


::

  class Rec extends com.adacore.ajis.internal.ada.AdaProxy {
     ...
     public void P(){...}
  }
  

You can then write:


::

  class Rec_Child extends Rec {
       public void P () {
          System.out.println ("Hello from Java");
       }
  }
  ...
  Rec ref = new Rec_Child();
  ref.P();  // Displays "Hello from Java"
  

.. _Global_Variables_and_Constants:

Global Variables and Constants
==============================

.. index:: Global variables (mapping to Java)

A package containing global variables
(that is, variables declared in the package spec's visible part)
is mapped to a default class containing 'getter' and 'setter'
methods for accessing and updating the variables. Global constants
are treated analogously, but they have only a 'getter' method.
Variables of limited types also only have a 'getter' method.
Note that Ada named numbers, which are really just values intended
for use in static compile-time computations, are not mapped to
Java.

For example:


::

  package Globals is
     V : Integer;
     C : constant Integer := 100;
     N : constant := 3.14159;
  end Globals;
  

will result in the default class:


::

  public class Globals_Package {

     static public int V (){...}

     static public void V (int Value){...}

     static public int C (){...}
  }
  

.. _Subprograms:

Subprograms
===========

.. index:: Subprograms (mapping to Java)

Ada procedures and functions are mapped to Java methods. Nondispatching
subprograms are marked as ``final``.  Dispatching subprograms are
discussed in :ref:`Tagged_Types`.

.. _Method_placement:

Method placement
----------------

In general, nondispatching subprograms are mapped to methods defined in the
default class.

.. index:: Default class

For example, if the input package spec is:


::

  package Pkg is
    function F return Integer;
  end Pkg;
  

then ``ada2java`` will generate the following default class:


::

  public class Pkg_Package{
     ...
     public static int F(){...}
  }
  

However, there are cases where the subprogram can be attached to the class
of its first parameter. Attachment can be enabled / disabled depending on
user requirement. In this case, the explicit initial Ada parameter is mapped to
the implicit ``this`` parameter in Java. See :ref:`Managing_Attachment_to_Java_Proxies` for further details.

.. index:: Attachment (of entities to a class)

.. _Subprogram_parameters:

Subprogram parameters
---------------------

.. index:: Parameters (mapping to Java)

The following rules and restrictions apply to the types of subprogram
formal parameters:

* Scalar types

  * Access-to-scalar types are not supported.

  * A scalar type with mode ``in`` is mapped to the
    corresponding Java type. For example:


    ::

      procedure P (V : Integer);
      

    will result in:


    ::

      public void P (int V) {...}
      

  * A formal scalar with mode ``out`` or ``in out`` will be mapped to
    a corresponding 'wrapper' class: ``BooleanRef``, ``CharacterRef``,
    ``DoubleRef``, ``IntegerRef``, and ``LongRef`` respectively
    encapsulating the primitive type ``boolean``, ``character``,
    ``double``, ``int`` and ``long``).

    Each of these classes defines ``setValue`` and ``getValue`` methods
    for accessing the encapsulated value.

    The Java application needs to construct an object of the relevant wrapper
    class and pass it to the method that corresponds to the Ada subprogram.
    After the return from the method, the Java application can invoke the
    ``getValue`` method to retrieve the new value of the actual parameter.

* Record and private types

  * 
    An Ada ``in``, ``in out``, or ``out`` formal parameter of a record
    or private type (either tagged or untagged), is mapped to a Java formal
    parameter of the class corresponding to the Ada type. Similarly, an Ada
    formal parameter of an access-to-record-type or access-to-private-type
    (either anonymous or named) is mapped to a Java formal parameter of the
    class corresponding to the Ada type.

    Example:


    ::

      package Example is
         type R is null record;
         type Access_R is access all R;
         procedure P(V1 : R;
                     V2 : out R;
                     V3 : in out R;
                     V4 : access R;
                     V5 : Access_R);
      end Example;
      

    The resulting Java class is:


    ::

      public final class Example_Pckg {
         ...
         public void P (R V1, R V2, R V3, R V4, R V5){...}
      }
      

  * 
    An Ada ``out`` or ``in out`` parameter of an access-to-record
    (or access-to-private) type is mapped to a nested class.
    For example:


    ::

      package Example is
         type R is null record;
         type Access_R is access all R;
         procedure P(V : out Access_R);
      end Example;
      

    will generate the default class and a class for ``R``


    ::

      public class Example_Package {
         ...
         static public void P (R.Ref V){...}
      }

      public class R extends com.adacore.ajis.internal.ada.AdaProxy {
         ...
         public static class Ref implements com.adacore.ajis.IProxyRef {
            public void setValue (Object r) {...}
            public Object getValue () {...}
         }
      }
      

    The Java application needs to construct an object of the class ``R.Ref``
    and pass it to ``P``.  On return, the ``getValue`` method may be
    called to retrieve the value in the ``out`` parameter returned by
    the Ada procedure.

  * Further indirection, such as an access-to-access type for a formal
    parameter, is not supported.

.. _Overloaded_operators:

Overloaded operators
--------------------

Java doesn't allow operators overloading. When operators are overloaded in
Ada, the corresponding Java name is set by the binding generator to
``OP_<operator_name>``. For example:


::

  type Complex is record ...

  function "+" (Left, Right : T) return T;
  

will generate on the Java side:


::

  public class Complex {

     public Complex OP_PLUS (Complex Right) {
     ...
     }

  }

  
Here's a list of the equivalence between Ada operators and Java names:

+--------------+--------------+
| Ada operator | Java name    |
+==============+==============+
| ``=``        | ``OP_EQUAL`` |
+--------------+--------------+
| ``>``        | ``OP_GT``    |
+--------------+--------------+
| ``<``        | ``OP_LT``    |
+--------------+--------------+
| ``>=``       | ``OP_GE``    |
+--------------+--------------+
| ``<=``       | ``OP_LE``    |
+--------------+--------------+
| ``or``       | ``OP_OR``    |
+--------------+--------------+
| ``and``      | ``OP_AND``   |
+--------------+--------------+
| ``xor``      | ``OP_XOR``   |
+--------------+--------------+
| ``+``        | ``OP_PLUS``  |
+--------------+--------------+
| ``-``        | ``OP_MINUS`` |
+--------------+--------------+
| ``/``        | ``OP_DIV``   |
+--------------+--------------+
| ``*``        | ``OP_MUL``   |
+--------------+--------------+
| ``**``       | ``OP_EXP``   |
+--------------+--------------+

.. _Subprogram_Access_Types:

Subprogram Access Types
=======================

Accesses to subprograms - sometimes referred to as callbacks - can't be
directly bound to Java. It is not possible to give a reference to a Java
function in a type-safe fashion. ada2java generates an abstract class with
an abstract member of the correct profile for each access type to be bound,
the implementation of its abstract primitive being the implementation of
the subprogram access. For example:


::

  type P_Acc is access all procedure (V : Integer);

  procedure Call_P_Acc (Proc : P_Acc);
  pragma Annotate (AJIS, Assume_Escaped, False, Call_P_Acc, "Proc");
  

will be bound into:


::

  abstract public class P_Acc {
     abstract public P_Acc_Proc (int V);
  }

  void Call_P_Acc (P_Acc Proc);
  

and can be used in, for example, the following scenario:


::

  Proc p = new Proc () {

     public P_Acc_Proc (int V) {
        System.out.println ("CALLED WITH " + V);
     }

  };

  Pckg_Package.Call_P_Acc (p);
  

Note the use of the pragma ``Annotate`` on the ``Call_P_Acc`` method.
The Java implementations of bound subprogram access types are not actually
accesses to subprograms, but instances of Java objects. It's not possible to
store such an object on the Ada side afterwards, since the complete information
can't be kept in the access type. Therefore, the programmer must ensure that
no escape of the value is done, and take responsiblity for that by declaring
the parameter as being not escaped. Further details on escapement can be found
in :ref:`Restrictions_on_Proxy-Owned_Objects_passed_to_Subprograms`.

.. _Exceptions:

Exceptions
==========

Exceptions are bound into classes derived from
``com.adacore.ajis.NativeException`` It is then possible to throw or
handle them directly in Java code.

Example:


::

  package Example is
     An_Exception : exception;
     procedure Raise_An_Exception;
  end Example;

  package body Example is
     procedure Raise_An_Exception is
     begin
        raise An_Exception;
     end Raise_An_Exception;
  end Example;
  

The resulting Java class is:


::

  public final class An_Exception extends com.adacore.ajis.NativeException {
     ...
  }
  

And can be used in e.g.:


::

  try {
     Example_Package.Raise_An_Exception ();
  } catch (An_Exception e) {
    // process the exception
  }
  

.. _Renamings:

Renamings
=========

.. index:: Renamings (mapping to Java)

Renamings of objects and subprograms are supported by ``ada2java``.
Object renamings are mapped in the same way as global objects, by means
of 'setter' and 'getter' methods in the default class for the
containing package.  A subprogram renaming is represented by a method
with the name of the renaming that invokes the renamed subprogram,
declared in the appropriate class.  In other words, the same rules
that apply to other subprograms apply to subprogram renamings.

.. _Generics:

Generics
========

Generic packages and subprogram can't be directly bound to Java. However,
packages and subprograms instances and bound like regular packages and
subprograms.

.. _Predefined_Environment:

Predefined Environment
======================

.. index:: Predefined environment (mapping to Java)

In order to access descendants of ``Ada`` or ``GNAT`` from Java,
you need to manually invoke ``ada2java`` on the Ada source files
from the GNAT installation directories, to generate the corresponding
Java binding classes.  This step will be automated in a future release of
GNAT-AJIS.

.. _Current_Limitations:

Current Limitations
===================

.. index:: Current limitations

The following features are not supported:

* 
  *Discriminants.*
  Discriminants are not accessible from the Java class generated for
  a discriminated type.

* 
  *Anonymous arrays.*
  Objects with an anonymous array type are not supported, but array type
  declarations which declare a constrained first subtype are supported.

* 
  *Interfaces.*
  No mapping is currently provided from Ada interface types to Java interfaces.

* 
  *Tasking features.*
  Tasks and protected objects/types are ignored.

