SpeADL Minus Reference » Historique » Révision 65
Révision 64 (Anonyme, 16/10/2014 10:08) → Révision 65/69 (Anonyme, 16/10/2014 10:11)
h1. SpeADL⁻ Reference Guide
{{>toc}}
In SpeADL, a subset of abstractions are provided to define traditional component-oriented architectures.
This subset of SpeADL is sometimes called SpeADL⁻ (pronounced SpeADL Minus).
With it, it is possible to define software components and compositions of components, called composites, implemented in Java.
A strong link between definition and implementation is kept by relying on an Eclipse plugin and automatic code generation.
A component is made of two elements: a definition using SpeADL and an implementation using Java.
The SpeADL definition acts a type declaration but can also describe a composition of components connected together.
For the implementation of components, the reader can refer to the [[SpeADL Minus Java Reference|Java for SpeADL⁻ reference guide]].
h2. Terminology
The reader can refer to the [[MAY Terminology]] document to get an overview of the different terms used in SpeADL.
h2. Namespaces
A namespace plays the same role as a package in Java except that it is not tied to a particular directory hierarchy.
h3. Keyword
Namespaces are declared using the keyword *namespace*.
h3. Details
In a SpeADL file, there can be many as namespaces as wanted.
They can also be nested ones.
Hence a namespace does not have to follow the name of the directory it is located in (as it is the case in Java).
h3. Example
<pre>
namespace simple {
namespace things {
}
}
namespace simple.things {
}
namespace simple.stuffs {
}
</pre>
h2. Imports
As in Java, it is possible to import existing names to avoid referring to them with their fully qualified name (i.e., including their package or namespace).
h3. Keyword and Role
The syntax is similar to Java: it uses the keyword *import*.
h3. Details
Imports are always situated at the top of a SpeADL file.
The namespace of component definitions can also be imported.
h3. Example
<pre>
import java.util.Collection
import java.util.*
import simple.stuffs.*
</pre>
h2. Component Definition
A software component is made of a definition and an implementation: an instance can then be created from the implementation.
A component definition has provided and required ports.
Optionally, a composite component definition contains parts that are themselves components.
h3. Keywords
A component definition is declared with the keyword *component* followed by a name starting with a capital letter.
The name must be unique in its namespace, but many components can be declared in the same namespace in the same SpeADL file.
The keywords *provides* and *requires* are used to declare, respectively, provided and required ports.
They are followed by a name (unique in the component and without capital letter) and an interface name separated by the character *: *.
It takes the form _provides name: Interface_ or _requires name: Interface_, where _Interface_ is a Java type.
The keyword *part* is used to declare a part in a composite component definition
It is followed by a name for the part (unique in the component and without capital letter) and the name of a component definition separated by the character *: *.
It takes the form _part name: ComponentName_.
For each part, bindings are used to declare for each of its required port what is fulfilling the requirement.
It is done using the keywords *bind* and *to* in the form _bind ...1 to ...2_ where _...1_ is the name of the required port of the part and _...2_ is a reference to a port available in the component containing the part.
Such a reference can either be:
* To another part's provided port, taking the form _bind req to name.port_.
* A provided or a required port of the current containing component, taking the form _bind req to port_.
A delegation is used to declare for the provided port of a component what other port will provides its implementation.
It is done using the keyword * = * followed by a reference to a port available in the current containing component (as with bindings).
It takes the form _provides name: Interface = name.port_ or _provides name: Interface = port_.
h3. Details
An interface is understood as a Java interface, i.e., a collection of methods, and must be visible in the classpath of the Java project.
For a composite component definition to be considered valid, all the required ports of its parts must be bound.
h3. Example
Component definitions:
<pre>
import my.interfaces.*
namespace simple.stuffs {
component MySimpleComponent {
provides p1: AnotherJavaInterface
}
component MyBeautifulComponent {
provides portName: AJavaInterface
requires anotherPortName: AnotherJavaInterface
}
component MyCompositeComponent {
provides p1: AnotherJavaInterface
provides p2: AnotherJavaInterface = s.p1
requires p3: AnotherJavaInterface
part b1: MyBeautifulComponent {
bind anotherPortName to s.p1
}
part b2: MyBeautifulComponent {
bind anotherPortName to p1
}
part b3: MyBeautifulComponent {
bind anotherPortName to p3
}
part s: MySimpleComponent
}
}
</pre>
Interface definition in Java:
<pre>
package my.interfaces;
public interface AJavaInterface {
public String aMethod(Integer param1);
public String anotherMethod();
}
</pre>
<pre>
package my.interfaces;
public interface AnotherJavaInterface {
public Integer test();
}
</pre>
h2. Component Specialisation
In SpeADL, a basic mechanism exists for specialisation of components.
h3. Keyword
When declaring a component definition, after the name, the keyword *specializes*, followed by component definition name, can be used.
h3. Details
An implementation of a specialising component can be used in place of the implementation of the specialised component.
Only the specialising component needs to be implemented: its implementation will contain all the provided ports of the specialisation hierarchy as well as the parts of the specialising component.
The specialisation rules are as follow:
* A component can specialise only a component without parts.
* A component can override provided ports (while respecting the interface constraint) to define delegation.
* A component can add provided ports.
* A component CAN'T add required ports.
h3. Examples
Specialising, adding a provided port and overriding a provided port:
<pre>
namespace simple.stuffs {
component S specializes MySimpleComponent {
provides p2: AnotherJavaInterface
provides p1: AnotherJavaInterface = p2
}
}
</pre>
h2. Type Parameters
As in Java, it is possible to exploit type parameters (also called generics) when declaring and referencing components, as well as in the interfaces of the ports.
h3. Keywords
Type parameters are enclosed between *[ * and * ]*. * ]* (contrary to Java where * <* and *> * are used).
A type parameter can be declared only in a component definition, just after the name declaration.
It has a unique name, a capital first letter, and can be constrained using the keyword *extends* and the name of a Java type class it must be a subclass of.
A type parameter can be used as an argument when referencing a component by its name, in a part or in a specialisation declaration.
It must respect the type parameters declared in the referenced component.
A type parameter can also be used as an argument when referencing an interface by its name in place of any a port declaration.
Again it must respect the type value. parameters declared in the interface.
h3. Details
The possibilities of expressiveness are equivalent to what can be done in Java.
The implementation can either keep the type parameters abstract as in the definition, or can concretise them as long as it respects the type parameter declaration.
Of course interface and component definition references can be parametrised with existing concrete classes.
h3. Example
<pre>
namespace simple.stuffs {
component ParameterisedComponent1[T extends Number] {
provides p1: java.util.concurrent.Callable[T]
provides p2: java.util.concurrent.Callable[String]
}
component ParameterisedComponent2[T1,T2 extends Number] {
part p1: ParameterisedComponent1[T2] {
}
part p2: ParameterisedComponent1[Integer] {
}
}
}
</pre>