Java 2 Ada

To content | To menu | To search

Dev › Ada

Entries feed

Friday, February 15 2013

Ada Web Application 0.3.0 is available

Ada Web Application is a framework to build web applications.

  • AWA uses Ada Server Faces for the web framework. This framework is using several patterns from the Java world such as Java Server Faces and Java Servlets.
  • AWA provides a set of ready to use and extendable modules that are common to many web application. This includes managing the login, authentication, users, permissions.
  • AWA uses an Object Relational Mapping that helps in writing Ada applications on top of MySQL or SQLite databases. The ADO framework allows to map database objects into Ada records and access them easily.
  • AWA is a model driven engineering framework that allows to design the application data model using UML and generate the corresponding Ada code.

Ada Web Application Architecture

The new version of AWA provides:

  • New jobs plugin to manage asynchronous jobs,
  • New storage plugin to manage a storage space for application documents,
  • New votes plugin to allow voting on items,
  • New question plugin to provide a general purpose Q&A.

AWA can be downloaded at http://code.google.com/p/ada-awa/downloads/list

A live demonstration of various features provided by AWA is available at http://demo.vacs.fr/atlas

Sunday, February 10 2013

Dynamo 0.6.0 is available

Dynamo is a tool to help developers write some types of Ada Applications which use the Ada Server Faces or Ada Database Objects frameworks. Dynamo provides several commands to perform one specific task in the development process: creation of an application, generation of database model, generation of Ada model, creation of database.

The new version of Dynamo provides:

  • A new command build-doc to extract some documentation from the sources,
  • The generation of MySQL and SQLite schemas from UML models,
  • The generation of Ada database mappings from UML models,
  • The generation of Ada beans from the UML models,
  • A new project template for command line tools using ADO,
  • A new distribution command to merge the resource bundles.

The most important feature is probably the Ada code generation from a UML class diagram. With this, you can design the data model of an application using ArgoUML and generate the Ada model files that will be used to access the database easily through the Ada Database Objects library. The tool will also generate the SQL database schema so that everything is concistent from your UML model, to the Ada implementation and the database tables.

The short tutorial below indicates how to design a UML model with ArgoUML, generate the Ada model files, the SQL files and create the MySQL database.

The Dynamo tool is available at http://code.google.com/p/ada-gen.

To build Dynamo, you will need:

Ada Database Objects 0.4.0 is available

The Ada Database Objects is an Object Relational Mapping for the Ada05 programming language. It allows to map database objects into Ada records and access databases easily. Most of the concepts developped for ADO come from the Java Hibernate ORM. ADO supports MySQL and SQLite databases.

The new version brings:

  • Support to reload query definitions,
  • It optimizes session factory implementation,
  • It allows to customize the MySQL database connection by using MySQL SET

This version can be downloaded at http://code.google.com/p/ada-ado/downloads/list.

Wednesday, February 6 2013

Ada Server Faces 0.5.0 is available

Ada Server Faces is an Ada implementation of several Java standard web frameworks.

  • The Java Servlet (JSR 315) defines the basis for a Java application to be plugged in Web servers. It standardizes the way an HTTP request and HTTP response are represented. It defines the mechanisms by which the requests and responses are passed from the Web server to the application possibly through some additional filters.
  • The Java Unified Expression Language (JSR 245) is a small expression language intended to be used in Web pages. Through the expressions, functions and methods it creates the link between the Web page template and the application data identified as beans.
  • The Java Server Faces (JSR 314 and JSR 344) is a component driven framework which provides a powerful mechanism for Web applications. Web pages are represented by facelet views (XHTML files) that are modelized as components when a request comes in. A lifecycle mechanism drives the request through converters and validators triggering events that are received by the application. Navigation rules define what result view must be rendered and returned.

Ada Server Faces gives to Ada developers a strong web framework which is frequently used in Java Web applications. On their hand, Java developers could benefit from the high performance that Ada brings: apart from the language, they will use the same design patterns.

Ada Server Faces

The new version of Ada Server Faces is available and brings the following changes:

  • The Security packages was moved in a separate project: Ada Security,
  • New demo to show OAuth and Facebook API integration,
  • Integrated jQuery 1.8.3 and jQuery UI 1.9.2,
  • New converter to display file sizes,
  • Javascript support was added for click-to-edit behavior,
  • Add support for JSF session beans,
  • Add support for servlet error page customization,
  • Allow navigation rules to handle exceptions raised by Ada bean actions,
  • Support the JSF 2.2 conditional navigation,
  • New functions fn:escapeXml and fn:replace.

The new version can be downloaded on the Ada Server Faces project page. A live demo is available at http://demo.vacs.fr/demo.

Sunday, February 3 2013

Ada Utility Library 1.6.1 is available

Ada Utility Library is a collection of utility packages for Ada 2005. This release is provided as workarround release to avoid the gcc 4.7 bug 53737. It allows to build Ada Utility Library with gcc 4.7.2.

Sunday, January 20 2013

Ada Security 1.0.0 is available

Ada Security is a security framework which allows web applications to define and enforce security policies. The framework allows users to authenticate by using OpenID Authentication 2.0. Ada Security also defines a set of client methods for using the OAuth 2.0 protocol.

Ada Security Framework

  • A security policy manager defines and implements the set of security rules that specify how to protect the system or the resources.
  • A user is authenticated in the application. Authentication can be based on OpenID or another system.
  • A security context holds the contextual information that allows the security policy manager to verify that the user is allowed to access the protected resource according to the policy rules.

The Ada Security framework can be downloaded at Ada Security project page.

The framework is the core security framework used by Ada Server Faces and Ada Web Application to protect access to resources.

Wednesday, December 26 2012

Ada Utility Library 1.6.0 is available

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Support for HTTP clients (curl, AWS, ...)
  • Support for REST APIs using JSON
  • New operations To_JSON and From_JSON for easy object map serialization
  • Added a listeners to help implementing the observer/listener design patterns
  • Added support for wildcard mapping in serialization framework
  • New option -d <dir> for the unit test harness to change the working directory,
  • New example facebook.adb to show the REST support.

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.3). You can download this new version at http://code.google.com/p/ada-util/downloads/list.

Sunday, November 11 2012

Ada BFD 1.0 is available

Ada BFD is an Ada binding for the GNU Binutils BFD library.

It allows to read binary ELF, COFF files by using the GNU BFD. The Ada BFD library allows to:

  • list and scan the ELF sections of an executable or object file,
  • get the content of the ELF sections,
  • get access to the symbol table,
  • use the BFD disassembler

Version 1.0 of this Ada binding library is now available on Ada BFD. This new release bring the following changes:

  • Fixed installation of library
  • Added examples for BfdAda
  • Add support to use the disassembler

Saturday, November 3 2012

Reading a program symbol table with Ada BFD

The GNU Binutils provides support for reading and writing program files in various formats such as ELF, COFF. This support is known as the BFD, the Binary File Descriptor library (or the Big F*cking Deal). This article illustrates how an Ada application can use the BFD library to have access to a program symbol table.

Declarations

The Ada BFD library provides a set of Ada bindings that give access to the BFD library. A binary file such as an object file, an executable or an archive is represented by the Bfd.Files.File_Type limited type. The symbol table is represented by the Bfd.Symbols.Symbol_Table limited type. These two types hold internal data used and managed by the BFD library.

with Bfd.Files;
with Bfd.Sections;
with Bfd.Symbols;
...
  File    : Bfd.Files.File_Type;
  Symbols : Bfd.Symbols.Symbol_Table;

Opening the BFD file

The Open procedure must be called to read the object or executable file whose path is given as argument. The File_Type parameter will be initialized to get access to the binary file information. The Check_Format function must then be called to let the BFD library gather the file format information and verify that it is an object file or an executable.

Bfd.Files.Open (File, Path, "");
if Bfd.Files.Check_Format (File, Bfd.Files.OBJECT) then
    ...
end if;

Loading the symbol table

The symbol table is loaded by using the Read_Symbols procedure.

Bfd.Symbols.Read_Symbols (File, Symbols);

The resources used by the symbol table will be freed when the symbol table instance is finalized.

Looking for a symbol

Once the symbol table is loaded, we can use the Get_Symbol function to find a symbol knowing its name. If the symbol is not found, a Null_Symbol is returned.

Sym  : Bfd.Symbols.Symbol := Bfd.Symbols.Get_Symbol (Symbols, "_main");
...
if Sym /= Bfd.Symbols.Null_Symbol then
   --  Symbol found
end if;

Each symbol has the following set of information:

  • A name (it may not be unique),
  • A set of flags that describe the symbol (global, local, weak, constructor, TLS, ...),
  • A symbol value,
  • A section to which the symbol belongs.
Sec   : constant Bfd.Sections.Section := Bfd.Symbols.Get_Section (Sym);
Flags : constant Bfd.Symbol_Flags     := Bfd.Symbols.Get_Flags (Sym);
Value : constant Bfd.Symbol_Value    := Bfd.Symbols.Get_Value (Sym);

Before interpreting and using the symbol value returned by Get_Value, you must look at the section to check for an undefined symbol. Indeed, undefined symbols being not yet resolved by the linker they have no value and no section. You can check that by using the Is_Undefined_Section function:

if Bfd.Sections.Is_Undefined_Section (Sec) then
   Ada.Text_IO.Put_Line ("undefined symbol");
end if;

When the symbol is defined, you must look at the flags and also the section information to know more about it.

if (Flags and Bfd.Symbols.BSF_GLOBAL) /= 0 then
  Ada.Text_IO.Put_Line ("global symbol in section "
               & Bfd.Sections.Get_Name (Sec)
               & " := " & Bfd.Symbol_Value'Image (Value));
 
elsif (Flags and Bfd.Symbols.BSF_LOCAL) /= 0 then
  Ada.Text_IO.Put_Line ("local symbol in section "
               & Bfd.Sections.Get_Name (Sec)
               & " := " & Bfd.Symbol_Value'Image (Value));
 
else
  Ada.Text_IO.Put_Line ("other symbol in section "
                                     & Bfd.Sections.Get_Name (Sec)
                                     & " := " & Bfd.Symbol_Value'Image (Value));
end if;

Conclusion and references

Reading an executable symbol table has been made fairly simple with the use of the Ada BFD library. Furthermore, the library allows to scan the sections, read their content and even use the BFD disassembler.

symbol.adb
BFD Documentation

Tuesday, June 5 2012

Using the Facebook API

Through this article you will learn how to use the OAuth 2.0 framework to let an application access service provider APIs such as Facebook API, Google+ API and others. Althought this article uses Ada as programming language and Facebook as service provider, most part also applies to other programming languages and other service providers.

Overview

OAuth 2.0 is an open standard for authorization. It is used by service providers as authorization mechanism for most of their APIs. The authorization workflow is depicted below:

  • [1], first a user goes in the application which displays a link to the OAuth API provider asking the user to grant access to his data for the application,
  • [2], the user clicks on the authenticate link and grants access to the application,
  • [3.1], The OAuth server redirects the user to a callback URL and it provides an application grant code,
  • [3.3], The application ask the API provider to transform the grant code to an access token,
  • [4] The application invokes the API provider with the access token

OAuth Workflow

Registering the application

The first step is to register the application in the service provider (Facebook, Google+, Twitter, ...). This registration process is specific to the provider. From this registration, several elements will be defined:

  • An application id is allocated, This identifier is public. This is the client_id parameter in OAuth 2.0.
  • An application secret is defined. It must be kept private to the application. This is the secret parameter in OAuth 2.0.
  • A callback URL or domain name is registered in the service provider. As far as I'm concerned, I had to register the domain demo.vacs.fr.

Facebook OAuth

For the OAuth authorization process, we will use the Ada Security library and its Application type. We will extend that type to expose some EL variables and an EL method that will be used in the authorization process. The Ada Server Faces Application Example part 3: the action bean explains how to do that and many details will no be covered by this article.

type Facebook_Auth is new Security.OAuth.Clients.Application
     and Util.Beans.Basic.Readonly_Bean
     and Util.Beans.Methods.Method_Bean with private;
 
FB_Auth      : aliased Facebook.Facebook_Auth;

Before anything we have to initialize the Application type to setup the application identifier, the application secret, the provider URL and a callback URL.

FB_Auth.Set_Application_Identifier ("116337738505130");
FB_Auth.Set_Application_Secret ("xxxxxxxxxxx");
FB_Auth.Set_Application_Callback ("http://demo.vacs.fr/oauth/localhost:8080/demo/oauth_callback.html");

The first step in the OAuth process is to build the authorization page with the link that redirects the user to the service provider OAuth authorization process. The link must be created by using the Get_State and Get_Auth_Params functions provided by the Application type. The first one generates a secure unique key that will be returned back by the service provider. The second one builds a list of request parameters that are necessary for the service provider to identify the application and redirect the user back to the application once the authentication is done.

Id : constant String := "...";
State  : constant String := FB_Auth.Get_State (Id);
Params : constant String := FB_Auth.Get_Auth_Params (State, "read_stream");

For a Facebook authorization process, the URI would be created as follows:

URI : constant String := "https://www.facebook.com/dialog/oauth?" & Params;

For another service provider, the process is similar but the URL is different.

OAuth callback

When the user has granted access to his data, he will be redirected to the callback defined by the application. Most service providers will require that the OAuth callback be a public URL. If you want to run you application on localhost (which is the case when you are developing), you will need a second redirection. If you are using the Apache server, you can easily setup a rewrite rule:

RewriteRule ^/oauth/localhost:([0-9]+)/(.*) http://localhost:$1/$2 [L,R=302]

With the above rewrite rule, the callback given to the OAuth provider would look like:

http://demo.vacs.fr/oauth/localhost:8080/demo/oauth_callback.html

The OAuth provider will first redirect to the public internet site which will redirect again to localhost and port 8080.

Getting the OAuth access token

The next step is to receive the code parameter from the callback which grants the application access to the service provider API. For this, we will use an XHTML view file and a view action that will be executed when the page is displayed. When this happens, the EL method authenticate will be called on the facebook bean (ie, our FB_Auth instance).

<f:view xmlns:f="http://java.sun.com/jsf/core">
    <f:metadata>
        <f:viewAction action="#{facebook.authenticate}"/>
    </f:metadata>
</f:view>

The Authenticate procedure extracts from the request the OAuth state and code parameters. It verifies that the state parameter is a valid key that we submitted and it makes a HTTP POST request on the OAuth service provider to transform the code into an access token. This step is handled by the Ada Security library through the Request_Access_Token operation.

procedure Authenticate (From    : in out Facebook_Auth;
                        Outcome : in out Ada.Strings.Unbounded.Unbounded_String) is
   use type Security.OAuth.Clients.Access_Token_Access;
 
   F       : constant ASF.Contexts.Faces.Faces_Context_Access := ASF.Contexts.Faces.Current;
   State : constant String := F.Get_Parameter (Security.OAuth.State);
   Code  : constant String := F.Get_Parameter (Security.OAuth.Code);
   Session : ASF.Sessions.Session := F.Get_Session;
begin
   Log.Info ("Auth code {0} for state {1}", Code, State);
   if Session.Is_Valid then
      if From.Is_Valid_State (Session.Get_Id, State) then
         declare
            Acc : Security.OAuth.Clients.Access_Token_Access
              := From.Request_Access_Token (Code);
         begin
            if Acc /= null then
               Log.Info ("Access token is {0}", Acc.Get_Name);
               Session.Set_Attribute ("access_token",
                                      Util.Beans.Objects.To_Object (Acc.Get_Name));
            end if;
         end;
      end if;
   end if;
end Authenticate;

The access token must be saved in the user session or another per-user safe storage so that it can be retrieved later on. The access token can expire and if this happens a fresh new access token must be obtained.

Getting the Facebook friends

Until now we have dealt with the authorization process. Let's look at using the service provider API and see how the Ada Utility Library will help in this task.

Defining the Ada beans

To represent the API result, we will use an Ada bean object that can easily be used from a presentation page. For the Facebook friend, a name and an identifier are necessary:

type Friend_Info is new Util.Beans.Basic.Readonly_Bean with record
   Name : Util.Beans.Objects.Object;
   Id   : Util.Beans.Objects.Object;
end record;
type Friend_Info_Access is access all Friend_Info;

Having a bean type to represent each friend, we will get a list of friends by instantiating the Ada bean Lists package:

package Friend_List is new Util.Beans.Basic.Lists (Element_Type => Friend_Info);

Mapping JSON or XML to Ada

The Ada Utility library provides a mechanism that parses JSON or XML and map the result in Ada objects. To be able to read the Facebook friend definition, we have to define an enum and implement a Set_Member procedure. This procedure will be called by the JSON/XML parser when a given data field is recognized and extracted.

type Friend_Field_Type is (FIELD_NAME, FIELD_ID);
 
procedure Set_Member (Into : in out Friend_Info;
                      Field : in Friend_Field_Type;
                      Value : in Util.Beans.Objects.Object);

The Set_Member procedure is rather simple as it just populates the data record with the value.

procedure Set_Member (Into : in out Friend_Info;
                      Field : in Friend_Field_Type;
                      Value : in Util.Beans.Objects.Object) is
begin
   case Field is
      when FIELD_ID =>
         Into.Id := Value;
 
      when FIELD_NAME =>
         Into.Name := Value;
 
   end case;
end Set_Member;

The mapper is a package that defines and controls how to map the JSON/XML data fields into the Ada record by using the Set_Member operation. We just have to instantiate the package. The Record_Mapper generic package will map JSON/XML into the Ada record and the Vector_Mapper will map a list of JSON/XML elements following a given structure into an Ada vector.

package Friend_Mapper is
  new Util.Serialize.Mappers.Record_Mapper (Element_Type        => Friend_Info,
                                            Element_Type_Access => Friend_Info_Access,
                                            Fields              => Friend_Field_Type,
                                            Set_Member          => Set_Member);
 
package Friend_Vector_Mapper is
   new Util.Serialize.Mappers.Vector_Mapper (Vectors        => Friend_List.Vectors,
                                             Element_Mapper => Friend_Mapper);

Now we need to control how the JSON/XML fields are mapped to our Ada fields. For this we have to setup the mapping. The Facebook JSON structure is so simple that we can use the default mapping provided by the mapper. For this we use the Add_Default_Mapping procedure. We also have to tell what is the JSON mapping used by the friend vector mapper.

Friend_Map        : aliased Friend_Mapper.Mapper;
Friend_Vector_Map : aliased Friend_Vector_Mapper.Mapper;
...
   Friend_Map.Add_Default_Mapping;
   Friend_Vector_Map.Set_Mapping (Friend_Map'Access);

Creating the REST client

Now it would be nice if we could get an operation that invokes the service provider API through an HTTP GET operation and put the result in our Ada object. The Facebook friends API returns a list of friends which correspond to our Friend_List.Vectors. To get our operation, we just have to instantiate the Rest_Get_Vector operation with our vector mapper (the generic parameter is a package name).

procedure Get_Friends is
  new Util.Http.Rest.Rest_Get_Vector (Vector_Mapper => Friend_Vector_Mapper);

Calling the REST client

Invoking the service provider API is now as simple as calling a procedure. The URI must include the access token as parameter. The HTTP GET operation must be made using SSL/TLS since this is part of OAuth 2.0.

 List  : Friend_List.List_Bean;
...
   Get_Friends ("https://graph.facebook.com/me/friends?access_token="
                      & Token,
                      Friend_Vector_Map'Access,
                      "/data",
                      List.List'Access);

Now you are ready to use and access the user's data as easily as other information...

References

facebook.ads
facebook.adb
Facebook API

Thursday, May 24 2012

AWA 0.2 is available

Ada Web Application is a framework to build web applications easily on top of Ada Server Faces, Ada Database Objects and Ada Web Server.

The new version of the framework provides:

  • A new event framework with configurable action listeners,
  • Persistent event queues for the event framework,
  • A new blog module and wiki engine supporting Google Wiki, Creole, MediaWiki, phpPP and Dotclear syntax,
  • New mail UI components allowing to generate and send email easily with the ASF presentation pages,
  • A new Javascript plugin Markedit with jQuery Markedit (MIT License)

This new version can be downloaded at http://code.google.com/p/ada-awa/downloads/list (downloading the awa-all package is recommended to get the project and its dependencies).

A demo of an AWA application is available at http://demo.vacs.fr/atlas/

Tuesday, May 22 2012

Atlas, the Ada Web Application demonstrator

AWA is a framework to build web applications on top of various robust components.

  • AWA uses Ada Server Faces for the web framework. This framework is using several patterns from the Java world such as Java Server Faces and Java Servlets.
  • AWA is architectured arround modules and plugins that allow to build, re-use and extend modules made of Ada code, Web pages or Javascript.
  • AWA provides a set of ready to use and extendable plugins that are common to many web application. This includes managing the login, authentication, users, permissions, a mail plugin, a blog plugin, a Javascript light editor.
  • AWA uses an Object Relational Mapping that helps in writing Ada applications on top of MySQL or SQLite databases. The ADO framework allows to map database objects into Ada records and access them easily.
  • AWA integrates a configurable event service which allows plugins to easily interact and connect with each other (either synchronously or asynchronously). The event service provided by AWA is heavily inspired from the Java Message Service.

To learn more on how to create easily a web application using AWA, look at the 4 minutes video.

The Atlas Web Application Demonstrator is a demonstration of an application using this AWA framework.

Sunday, May 20 2012

Dynamo 0.5.0 is available

Dynamo is a tool to help developers write an Ada Web Application using the Ada Server Faces and the Ada Database Objects frameworks. Dynamo provides several commands to perform one specific task in the development process: creation of an application, generation of database model, generation of Ada model, creation of database.

The new version of Dynamo provides:

  • Support multi-line comments in XML mappings,
  • Generate List_Bean types for the XML mapped queries,
  • Add support for Ada enum generation,
  • Add test template generation,
  • Add AWA service template generation,
  • Add support for blob model mapping,
  • New command 'add-ajax-form', 'add-query', 'dist', 'create-plugin'

The Dynamo tool is available at http://code.google.com/p/ada-gen. To build Dynamo, you will need:

Saturday, May 12 2012

Ada Database Objects 0.3.0 is available

The Ada Database Objects is an Object Relational Mapping for the Ada05 programming language. It allows to map database objects into Ada records and access databases easily. Most of the concepts developped for ADO come from the Java Hibernate ORM. ADO supports MySQL and SQLite databases.

The new version brings:

  • Support to update database records when a field is really modified,
  • Customization of the SQLite database connection by using SQLite PRAGMAs,
  • Escape of MySQL or SQLite reserved keywords,
  • Support for blob type.

This version can be downloaded at http://code.google.com/p/ada-ado/downloads/list.

Friday, May 11 2012

Ada Server Faces 0.4.0 is available

Ada Server Faces is a web framework which uses the Java Server Faces design patterns (See JSR 252, JSR 314 or the latest one the JSR 344).

This new version brings a serious step ahead towards JSF compatibility. This new version provides:

  • Support for shared or static build configuration,
  • Support for file upload,
  • New components <h:inputFile>, <f:metadata>, <f:viewParam>, <f:viewAction>,
  • New EL function util:hasMessage,
  • ASF now Implements the JSF phase events and phase listeners,
  • Implements the JSF/Ruby on Rails flash context,
  • Adds the pre-defined JSF beans: initParam, flash,
  • Support for locales and honors the Accept-Language,
  • New demos are available in French and English

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-asf/downloads/list.

A live demo is available at: http://demo.vacs.fr.

Feel free to play with the OpenID stuff!!!

Wednesday, May 9 2012

Ada Utility Library 1.5.0 is available

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Concurrent fifo queues and arrays
  • Changed Objects.Maps to use a String instead of an Unbounded_String as the key
  • Support for shared or static build configuration
  • Implementation of input/output/error redirection to a file for process launch

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-util/downloads/list.

Tuesday, February 14 2012

Ada Server Faces 0.3.0 is available

Ada Server Faces is a web framework which uses the Java Server Faces design patterns (See JSR 252 and JSR 314).

JSF and ASF use a component-based model for the design and implementation of a web application. The presentation layer is implemented using XML or XHTML files and the component layer is implemented in Ada 05 for ASF and in Java for JSF.

A new version of ASF is available which provides:

  • New components used in HTML forms (textarea, select, label, hidden),
  • New components for the AJAX framework,
  • Support for dialog boxes with jQuery UI,
  • Pre-defined beans in ASF contexts: param, header,
  • A complete set of example and documentation for each tag.

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-asf/downloads/list.

A live demo is available at: http://demo.vacs.fr.

Tuesday, January 17 2012

Ada perfect hash generation with gperfhash

A perfect hash function is a function that returns a distinct hash number for each keyword of a well defined set. gperf is famous and well known perfect hash generator used for C or C++ languages. Ada is not supported.

The gperfhash is a sample from the Ada Utility Library which generates an Ada package that implements such perfect hash operation. It is not as complete as gperf but allows to easily get a hash operation. The gperfhash tool uses the GNAT package GNAT.Perfect_Hash_Generators.

Pre requisite

Since the gperfhash tool is provided by the Ada Util samples, you must build these samples with the following command:

$ gnatmake -Psamples

Define a keyword file

First, create a file which contains one keyword on each line. For example, let's write a keywords.txt file which contains the following three keywords:

int
select
print

Generate the package

Run the gperfhash tool and give it the package name.

$ gperfhash -p Hashing keywords.txt

The package defines a Hash and an Is_Keyword function. The Hash function returns a hash number for each string passed as argument. The hash number will be different for each string that matches one of our keyword. You can give a string not in the keyword list, in that case the hash function will return a number that collides with a hash number of one or our keyword.

The Is_Keyword function allows to check whether a string is a keyword of the list. This is very useful when you just want to know whether a string is a reserved keyword in some application.

The package specification is the following:

--  Generated by gperfhash
package Hashing is
 
   function Hash (S : String) return Natural;
 
   --  Returns true if the string <b>S</b> is a keyword.
   function Is_Keyword (S : in String) return Boolean;
 
   type Name_Access is access constant String;
   type Keyword_Array is array (Natural range <>) of Name_Access;
   Keywords : constant Keyword_Array;
private
...
end Hashing;

How to use the hash

Using the perfect hash generator is simple:

with Hashing;
 
  if Hashing.Is_Keyword (S) then
     -- 'S' is one of our keyword
  else
     -- No, it's not a keyword
  end if;

Sunday, January 15 2012

Ada Utility Library 1.4.0 is available

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Support for localized date format,
  • Support for process creation and pipe streams (on Unix and Windows),
  • Support for CSV in the serialization framework,
  • Integration of Ahven 2.1 for the unit tests (activate with --enable-ahven),
  • A tool to generate perfect hash function

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-util/downloads/list.

Sunday, November 27 2011

Aunit vs Ahven

AUnit and Ahven are two testing frameworks for Ada. Both of them are inspired from the well known JUnit Java framework. Having some issues with the Aunit testing framework, I wanted to explore the use of Ahven. This article gives some comparison elements between the two unit test frameworks. I do not pretend to list all the differences since both frameworks are excellent.

Writing a unit test is equally simple in both frameworks. They however have some differences that may not be visible at the first glance.

AUnit

AUnit is a unit test framework developped by Ed Falis and maintained by AdaCore. It is distributed under the GNU GPL License.

Some good points:

  • AUnit has a good support to report where a test failed. Indeed, the Assert procedures will report the source file and line number where the assertion failed.
  • AUnit is also able to dump the exception stack trace in symbolic form. This is useful to find out quickly the source of a problem.

Some bad points:

  • AUnit has several memory leaks which is quite annoying when you want to track memory links with valgrind.
  • AUnit does not integrate easily with JUnit-based XML tools. In particular the XML file it creates can be invalid in some cases (special characters in names). More annoying is the fact that the XML format is not compatible with JUnit XML format.

Ahven

Ahven is another unit test framework developped by Tero Koskinen. It is distributed under the permissive ISC License.

Some good points:

  • Ahven license is a better model for proprietary unit tests.
  • Ahven generates XML result files which are compatible with Junit XML result files. Integration with automatic build tools such as Jenkins is easier.
  • Ahven XML result files can integrate the test output (as in JUnit). This is useful to analyze a problem.
  • Ahven has a test case timeout which is useful to detect and stop blocking tests.

Some bad points:

  • The lack of precise information in message (source line, exception trace) can be annoying to find out why a test failed.

Don't choose and be prepared to use both with Ada Util!

The unit tests I've written were done for AUnit and I had arround 329 tests to migrate. To help the migration to Ahven, I wrote a Util.XUnit package which exposes a common interface on top of AUnit or Ahven. It turns out that this is easy and quite small. The package has one specific implementation (spec+body) for both frameworks. All the unit tests have to use it instead of the AUnit or Ahven packages.

The Aunit implementation (util-xunit.ads) defines several types which are also defined in the Ahven implementation.

package Util.XUnit is
...
   subtype Status is AUnit.Status;

   Success : constant Status := AUnit.Success;
   Failure : constant Status := AUnit.Failure;

   subtype Message_String is AUnit.Message_String;
   subtype Test_Suite is AUnit.Test_Suites.Test_Suite;
   subtype Access_Test_Suite is AUnit.Test_Suites.Access_Test_Suite;

   type Test_Case is abstract new AUnit.Simple_Test_Cases.Test_Case with null record;
   type Test is abstract new AUnit.Test_Fixtures.Test_Fixture with null record;
...
end Util.XUnit;

The XUnit implementation for Ahven is a little bit more complex because all my tests were using AUnit interface, I decided to keep almost that API and thus I had to simulate what is missing or is different.

Ahven implementation: util-xunit.ads

package Util.XUnit is
...
   type Status is (Success, Failure);

   subtype Message_String is String;
   subtype Test_Suite is Ahven.Framework.Test_Suite;
   type Access_Test_Suite is access all Test_Suite;

   type Test_Case is abstract new Ahven.Framework.Test_Case with null record;
   type Test is new Ahven.Framework.Test_Case with null record;
...
end Util.XUnit;

The choice of the unit test framework is done when the Ada Utility library is configured.

- page 1 of 2