Projet

Général

Profil

Actions

SpeADL Minus Tutorial » Historique » Révision 5

« Précédent | Révision 5/20 (diff) | Suivant »
Anonyme, 06/10/2014 15:53


SpeADL Minus Tutorial

This is a tutorial for SpeADL⁻: creating a project, defining simple and composite components, implementing components.

Objectives

The objective of this tutorial is to understand the basic workflow to follow when developing component-oriented applications with SpeADL in Eclipse/MAY.

We will create a simple composition of two components connected together following a typical client-server configuration.
The server will provide a service that will be used by the client.
They will be composed together in a big component.
A Java main() will be created to show how to execute the composition once.
A very simple GUI will be used to illustrate a self-contained component acting as an application.

Installing Eclipse and MAY

This procedure is described on this page.

Creating a New Project

First, we must create a project to work.

In Eclipse, go to the menus : File / New / Java Project.

Enter Tutorial 1 as the project name, verify that the execution environment JRE is 1.5 or above.

As a start, create a package in the src folder called tutorial1.

The Server Component

Organisation

Create the following hierarchy of packages (See this best practice for details on the matter):
  • tutorial1.server
    • impl
    • interfaces

Defining the Component

Create a SpeADL file:
  • Right-click on tutorial1.server and select New / File.
  • Enter server.speadl as the file name.

Define the namespace we are going to work in as well as the Server component:

namespace tutorial1.server {
    component ServerComponentType {

    }
}

Save and confirm that the speadl-gen folder was automatically added to the project source folders and that it contains a Java class generated in the package tutorial1.server named ServerComponentType.

Defining a Port and its Interface

The Server component will provide a port whose interface contains one method to give the contrary of a boolean.

Add it to the component declaration:

namespace tutorial1.server {
    component ServerComponentType {
        provides service: NotSoNiceServiceType
    }
}

Because the NotSoNiceServiceType interface does not yet exist, there is an error in the SpeADL editor.
We will store the interface in the tutorial1.server.interfaces package.

Either create it by hand or use the Quick Fix proposed by SpeADL editor by hovering on the error.

package tutorial1.server.interfaces;

public interface NotSoNiceServiceType {

    public boolean contrary(boolean b);
}

Save, and go back to the SpeADL editor for server.speadl.
Call the automatic import organiser with Ctrl+Shift+O.
Confirm that an import was added on top of the SpeADL file and save.

Implementing the Component

Create a new Java class in tutorial1.server.impl named ServerImpl, and edit it so that it extends ServerComponentType:

public class ServerImpl extends ServerComponentType {

}

Notice that completion can be exploited as ServerComponentType is an actual Java type, but that calling F3 on it redirects directly to the SpeADL file.

Because there is abstract method to implement in ServerComponentType, there is errors in the Java editor.
Use the Quick Fix Add unimplemented methods by hovering on the error on the class name ServerImpl:

public class ServerImpl extends ServerComponentType {

    @Override
    protected NotSoNiceServiceType make_service() {
        // TODO Auto-generated method stub
        return null;
    }

}

Remove the TODO line and replace null with new NotSoNiceServiceType, call completion (Ctrl+Space) and choose NotSoNiceServiceType() Anonymous Inner Type:

public class ServerImpl extends ServerComponentType {

    @Override
    protected NotSoNiceServiceType make_service() {
        return new NotSoNiceServiceType() {

            @Override
            public boolean contrary(boolean b) {
                // TODO Auto-generated method stub
                return false;
            }
        };
    }
}

Remove the TODO line and replace return false; by return !b;:

package tutorial1.server.impl;

import tutorial1.server.ServerComponentType;
import tutorial1.server.interfaces.NotSoNiceServiceType;

public class ServerImpl extends ServerComponentType {

    @Override
    protected NotSoNiceServiceType make_service() {
        return new NotSoNiceServiceType() {

            @Override
            public boolean contrary(boolean b) {
                return !b;
            }
        };
    }

}

The Client Component

Organisation

Create the following hierarchy of packages:
  • tutorial1.client
    • impl
    • interfaces
    • datatypes

Defining the Component

Create a SpeADL file in tutorial1.client named client.speadl.

Define the namespace we are going to work in as well as the Client component:

namespace tutorial1.client {
    component ClientComponentType {

    }
}

Save and confirm that the speadl-gen folder contains a Java class generated in the package tutorial1.client named ClientComponentType.

Defining the Ports, their Interfaces and Datatypes

The Client component will provides a port computing a request and will need the NotSoNiceServiceType to do its job:

import tutorial1.server.interfaces.NotSoNiceServiceType

namespace tutorial1.client {

    component ClientComponentType {
        provides service: ASupeNiceService
        requires helper: NotSoNiceServiceType
    }

}

Don't hesitate to exploit completion (Ctrl+Space) and automatic import organiser (Ctrl+Shift+O) to type the interfaces names.

As before, an error appears in the editor because ASupeNiceService does not exists, create it in tutorial1.client.interfaces:

package tutorial1.client.interfaces;

public interface ASupeNiceService {

    public Request compute(Request r);

}

As we can see, we rely on a type named Request.
Create it in tutorial1.client.datatypes:

package tutorial1.client.datatypes;

public class Request {

    public final boolean b;

    public Request(boolean b) {
        this.b = b;
    }
}

Implementing the Component

Create a new Java class in tutorial1.client.impl named ClientImpl.
Edit it so that it extends ClientComponentType and resolve all the errors to generate its complete skeleton:

package tutorial1.client.impl;

import tutorial1.client.ClientComponentType;
import tutorial1.client.datatypes.Request;
import tutorial1.client.interfaces.ASupeNiceService;

public class ClientImpl extends ClientComponentType {

    @Override
    protected ASupeNiceService make_service() {
        return new ASupeNiceService() {

            @Override
            public Request compute(Request r) {
                // TODO Auto-generated method stub
                return null;
            }
        };
    }

}

Implement the compute() method to call the required port helper to actually do the computation and to return a new Request:

public class ClientImpl extends ClientComponentType {

    @Override
    protected ASupeNiceService make_service() {
        return new ASupeNiceService() {
            @Override
            public Request compute(Request r) {
                final boolean contrary = requires().helper().contrary(r.b);
                return new Request(contrary);
            }
        };
    }
}

The Composite Component

In order to use the Client and the Server components together, we need to build a composite component connecting them together.

Defining the Component

Create a SpeADL file in tutorial1 named application.speadl.

Define the namespace we are going to work in as well as the Application component:

namespace tutorial1 {
    component Application {

    }
}

Save.

Defining the Composition

In Application, there will be one Server and one Client for now.
Declare them as parts in the Application component:

import tutorial1.client.ClientComponentType
import tutorial1.server.ServerComponentType

namespace tutorial1 {
    component Application {
        part server: ServerComponentType {

        }

        part client: ClientComponentType {

        }
    }
}

An error is present in the editor on the client name to express that some required ports of client are not bound.
Using the bind ... to ... keyword by it:

namespace tutorial1 {
    component Application {
        part server: ServerComponentType {

        }

        part client: ClientComponentType {
            bind helper to server.service
        }
    }
}

Save.

Implementing the Component

Mis à jour par Anonyme il y a plus de 11 ans · 20 révisions