SpeADL Minus Tutorial » Historique » Révision 4
Révision 3 (Anonyme, 06/10/2014 15:18) → Révision 4/20 (Anonyme, 06/10/2014 15:34)
h1. SpeADL Minus Tutorial {{>toc}} This is a tutorial for [[SpeADL Minus Reference|SpeADL⁻]]: creating a project, defining simple and composite components, implementing components. h2. 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. h2. Installing Eclipse and MAY This procedure is described on [[SpeADL MAY Project SetUp|this page]]. h2. 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_. h2. The Server Component h3. Organisation Create the following hierarchy of packages (See [[SpeADL Best Practices#Project Organisation|this best practice]] for details on the matter): * _tutorial1.server_ ** _impl_ ** _interfaces_ ** _datatypes_ h3. 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: <pre> namespace tutorial1.server { component ServerComponentType { } } </pre> 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_. h3. 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: <pre> namespace tutorial1.server { component ServerComponentType { provides service: NotSoNiceServiceType } } </pre> 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. <pre> package tutorial1.server.interfaces; public interface NotSoNiceServiceType { public boolean contrary(boolean b); } </pre> 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. h3. Implementing the Component Create a new Java class in _tutorial1.server.impl_ named ServerImpl, and edit it so that it extends ServerComponentType: <pre> package tutorial1.server.interfaces; public interface NotSoNiceServiceType { public boolean contrary(boolean b); } </pre> 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_: <pre> public class ServerImpl extends ServerComponentType { @Override protected NotSoNiceServiceType make_service() { // TODO Auto-generated method stub return null; } } </pre> Remove the *TODO* line and replace _null_ with _new NotSoNiceServiceType_, call completion (*Ctrl+Space*) and choose *NotSoNiceServiceType() Anonymous Inner Type*: <pre> 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; } }; } } </pre> Remove the *TODO* line and replace _return false;_ by _return !b;_: <pre> 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; } }; } } </pre> h2. The Client Component h3. Organisation Create the following hierarchy of packages (See [[SpeADL Best Practices#Project Organisation|this best practice]] for details on the matter): * _tutorial1.client_ ** _impl_ ** _interfaces_ ** _datatypes_ h3. 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: <pre> namespace tutorial1.client { component ClientComponentType { } } </pre> Save and confirm that the *speadl-gen* folder contains a Java class generated in the package _tutorial1.client_ named _ClientComponentType_. h3. 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: <pre> import tutorial1.server.interfaces.NotSoNiceServiceType namespace tutorial1.client { component ClientComponentType { provides service: ASupeNiceService requires helper: NotSoNiceServiceType } } </pre> 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_: <pre> package tutorial1.client.interfaces; public interface ASupeNiceService { public Request compute(Request r); } </pre> As we can see, we rely on a type named _Request_: create it in _tutorial1.client.datatypes_: <pre> package tutorial1.client.datatypes; public class Request { public final boolean b; public Request(boolean b) { this.b = b; } } </pre>