SpeADL Minus Reference » Historique » Version 53
Anonyme, 16/10/2014 09:50
| 1 | 50 | Anonyme | h1. SpeADL⁻ Reference Guide |
|---|---|---|---|
| 2 | 1 | Anonyme | |
| 3 | 2 | Anonyme | {{>toc}} |
| 4 | 1 | Anonyme | |
| 5 | 44 | Anonyme | In SpeADL, a subset of abstractions are provided to define traditional component-oriented architectures. |
| 6 | This subset of SpeADL is sometimes called SpeADL⁻ (pronounced SpeADL Minus). |
||
| 7 | 45 | Anonyme | With it, it is possible to define software components and compositions of components, called composites, implemented in Java. |
| 8 | A strong link between definition and implementation is kept by relying on an Eclipse plugin and automatic code generation. |
||
| 9 | 1 | Anonyme | |
| 10 | 48 | Anonyme | A component is made of two elements: a definition using SpeADL and an implementation using Java. |
| 11 | 45 | Anonyme | The SpeADL definition acts a type declaration but can also describe a composition of components connected together. |
| 12 | 48 | Anonyme | |
| 13 | 51 | Anonyme | For the implementation of components, the reader can refer to the [[SpeADL Minus Java Reference|Java for SpeADL⁻ reference guide]]. |
| 14 | 1 | Anonyme | |
| 15 | 35 | Anonyme | h2. Terminology |
| 16 | |||
| 17 | The reader can refer to the [[MAY Terminology]] document to get an overview of the different terms used in SpeADL. |
||
| 18 | |||
| 19 | 1 | Anonyme | h2. Namespaces |
| 20 | |||
| 21 | 46 | Anonyme | A namespace plays the same role as a package in Java except that it is not tied to a particular directory hierarchy. |
| 22 | 5 | Anonyme | |
| 23 | 4 | Anonyme | h3. Keyword |
| 24 | |||
| 25 | 31 | Anonyme | Namespaces are declared using the keyword *namespace*. |
| 26 | 1 | Anonyme | |
| 27 | 4 | Anonyme | h3. Details |
| 28 | |||
| 29 | 52 | Anonyme | In a SpeADL file, there can be many as namespaces as wanted. |
| 30 | They can also be nested ones. |
||
| 31 | Hence a namespace does not have to follow the name of the directory it is located in (as it is the case in Java). |
||
| 32 | 4 | Anonyme | |
| 33 | h3. Example |
||
| 34 | |||
| 35 | 1 | Anonyme | <pre> |
| 36 | namespace simple { |
||
| 37 | |||
| 38 | namespace things { |
||
| 39 | 19 | Anonyme | |
| 40 | 1 | Anonyme | } |
| 41 | } |
||
| 42 | |||
| 43 | 19 | Anonyme | namespace simple.things { |
| 44 | |||
| 45 | } |
||
| 46 | |||
| 47 | 1 | Anonyme | namespace simple.stuffs { |
| 48 | 19 | Anonyme | |
| 49 | 1 | Anonyme | } |
| 50 | </pre> |
||
| 51 | |||
| 52 | h2. Imports |
||
| 53 | |||
| 54 | 20 | Anonyme | 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). |
| 55 | 1 | Anonyme | |
| 56 | 5 | Anonyme | h3. Keyword and Role |
| 57 | |||
| 58 | As in Java, this is done with the keyword *import*. |
||
| 59 | |||
| 60 | h3. Details |
||
| 61 | |||
| 62 | 53 | Anonyme | Imports are always situated at the top of a SpeADL file. |
| 63 | The namespace of component definitions can also be imported. |
||
| 64 | 5 | Anonyme | |
| 65 | h3. Example |
||
| 66 | |||
| 67 | 1 | Anonyme | The syntax is similar to Java: |
| 68 | <pre> |
||
| 69 | import java.util.Collection |
||
| 70 | import java.util.* |
||
| 71 | import simple.stuffs.* |
||
| 72 | </pre> |
||
| 73 | |||
| 74 | 33 | Anonyme | h2. Component Definition |
| 75 | 1 | Anonyme | |
| 76 | 33 | Anonyme | A software component is made of a definition and an implementation: an instance can then be created from the implementation. |
| 77 | A component definition has provided and required ports, as well as parts which are themselves components. |
||
| 78 | 1 | Anonyme | A part is structurally similar to a class member in Java. |
| 79 | 5 | Anonyme | For each required port of a part, there must be a binding declaring what is providing the required port. |
| 80 | 1 | Anonyme | |
| 81 | h3. Keywords |
||
| 82 | |||
| 83 | 33 | Anonyme | A component definition is declared with the keyword *component* followed by a name starting with a capital letter. |
| 84 | It must be unique in its namespace. |
||
| 85 | 1 | Anonyme | |
| 86 | 43 | Frédéric Migeon | 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 *: *. |
| 87 | 1 | Anonyme | It takes the form _provides name: Interface_ or _requires name: Interface_, where _Interface_ is a Java type. |
| 88 | |||
| 89 | 31 | Anonyme | The keyword *part* is used to declare a part in a component. |
| 90 | 50 | Anonyme | 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 *: *. |
| 91 | 31 | Anonyme | It takes the form _part name: ComponentName_. |
| 92 | 5 | Anonyme | |
| 93 | 33 | Anonyme | For each part, bindings are used to declare for each of its required port what is fulfilling the requirement. |
| 94 | 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. |
||
| 95 | 5 | Anonyme | Such a reference can either be: |
| 96 | 31 | Anonyme | * To another part's provided port, taking the form _bind req to name.port_. |
| 97 | * A provided or a required port of the current containing component, taking the form _bind req to port_. |
||
| 98 | 5 | Anonyme | |
| 99 | 31 | Anonyme | A delegation is used to declare for the provided port of a component what other port will provides its implementation. |
| 100 | 33 | Anonyme | It is done using the keyword * = * followed by a reference to a port available in the current containing component (as with bindings). |
| 101 | 31 | Anonyme | It takes the form _provides name: Interface = name.port_ or _provides name: Interface = port_. |
| 102 | 5 | Anonyme | |
| 103 | h3. Details |
||
| 104 | |||
| 105 | 31 | Anonyme | 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. |
| 106 | 5 | Anonyme | |
| 107 | 33 | Anonyme | All the required of a part must be bound for the component definition to be valid. |
| 108 | 1 | Anonyme | |
| 109 | 5 | Anonyme | h3. Example |
| 110 | |||
| 111 | 50 | Anonyme | Component definitions: |
| 112 | 1 | Anonyme | <pre> |
| 113 | import my.interfaces.* |
||
| 114 | |||
| 115 | namespace simple.stuffs { |
||
| 116 | |||
| 117 | component MySimpleComponent { |
||
| 118 | provides p1: AnotherJavaInterface |
||
| 119 | } |
||
| 120 | |||
| 121 | component MyBeautifulComponent { |
||
| 122 | provides portName: AJavaInterface |
||
| 123 | requires anotherPortName: AnotherJavaInterface |
||
| 124 | } |
||
| 125 | |||
| 126 | 5 | Anonyme | component MyComplexComponent { |
| 127 | |||
| 128 | provides p1: AnotherJavaInterface |
||
| 129 | provides p2: AnotherJavaInterface = s.p1 |
||
| 130 | requires p3: AnotherJavaInterface |
||
| 131 | 1 | Anonyme | |
| 132 | 5 | Anonyme | part b1: MyBeautifulComponent { |
| 133 | bind anotherPortName to s.p1 |
||
| 134 | } |
||
| 135 | 1 | Anonyme | |
| 136 | 5 | Anonyme | part b2: MyBeautifulComponent { |
| 137 | bind anotherPortName to p1 |
||
| 138 | } |
||
| 139 | |||
| 140 | part b3: MyBeautifulComponent { |
||
| 141 | bind anotherPortName to p3 |
||
| 142 | } |
||
| 143 | |||
| 144 | part s: MySimpleComponent |
||
| 145 | |||
| 146 | } |
||
| 147 | } |
||
| 148 | </pre> |
||
| 149 | |||
| 150 | Interface definition in Java: |
||
| 151 | 1 | Anonyme | <pre> |
| 152 | package my.interfaces; |
||
| 153 | |||
| 154 | public interface AJavaInterface { |
||
| 155 | public String aMethod(Integer param1); |
||
| 156 | } |
||
| 157 | </pre> |
||
| 158 | |||
| 159 | <pre> |
||
| 160 | package my.interfaces; |
||
| 161 | |||
| 162 | public interface AnotherJavaInterface { |
||
| 163 | public Integer test(); |
||
| 164 | } |
||
| 165 | </pre> |
||
| 166 | |||
| 167 | 39 | Anonyme | h2. Component Specialisation |
| 168 | 16 | Anonyme | |
| 169 | In SpeADL, a basic mechanism exists for specialisation of components. |
||
| 170 | |||
| 171 | h3. Keyword |
||
| 172 | |||
| 173 | 50 | Anonyme | When declaring a component definition, after the name, the keyword *specializes*, followed by a reference to another component name, can be used. |
| 174 | 1 | Anonyme | |
| 175 | 16 | Anonyme | h3. Details |
| 176 | |||
| 177 | 33 | Anonyme | An implementation of a specialising component can be used in place of the implementation of the specialised component. |
| 178 | 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. |
||
| 179 | |||
| 180 | The specialisation rules are as follow: |
||
| 181 | 1 | Anonyme | * A component can specialise only a component without parts (i.e., only a pure definition with provided and required ports). |
| 182 | 31 | Anonyme | * A component can override provided ports (while respecting the interface or specialising it) to define delegation. |
| 183 | 28 | Anonyme | * A component can add provided ports. |
| 184 | 33 | Anonyme | * A component CAN'T add required ports (for obvious reason: the specialising component wouldn't be usable in a configuration where the specialised component is used because some of its ports won't be bound). |
| 185 | 30 | Anonyme | |
| 186 | 16 | Anonyme | h3. Examples |
| 187 | |||
| 188 | <pre> |
||
| 189 | namespace simple.stuffs { |
||
| 190 | 26 | Anonyme | component S specializes MySimpleComponent { |
| 191 | provides p2: AnotherJavaInterface |
||
| 192 | 16 | Anonyme | } |
| 193 | } |
||
| 194 | </pre> |
||
| 195 | |||
| 196 | 15 | Anonyme | h2. Type Parameters |
| 197 | |||
| 198 | 33 | Anonyme | 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. |
| 199 | 1 | Anonyme | |
| 200 | h3. Keywords |
||
| 201 | |||
| 202 | 34 | Anonyme | Type parameters are enclosed between *[ * and * ]* (contrary to Java where * <* and *> * are used). |
| 203 | 1 | Anonyme | |
| 204 | A type parameter can be declared only in a component definition, just after the name declaration. |
||
| 205 | 33 | Anonyme | It has a unique name, a capital first letter, and can be constrained using the keyword *extends* and the name of a Java class it must be a subclass of. |
| 206 | 1 | Anonyme | |
| 207 | 33 | Anonyme | A type parameter can be used as an argument when referencing a component by its name, in a part or in a specialisation declaration. |
| 208 | 1 | Anonyme | It must respect the type parameters declared in the referenced component. |
| 209 | |||
| 210 | 33 | Anonyme | A type parameter can also be used as an argument when referencing an interface by its name in a port declaration. |
| 211 | 1 | Anonyme | Again it must respect the type parameters declared in the interface. |
| 212 | |||
| 213 | h3. Details |
||
| 214 | |||
| 215 | The possibilities of expressiveness are equivalent to what can be done in Java. |
||
| 216 | |||
| 217 | 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. |
||
| 218 | |||
| 219 | Of course interface and component definition references can be parametrised with existing concrete classes. |
||
| 220 | |||
| 221 | h3. Example |
||
| 222 | |||
| 223 | <pre> |
||
| 224 | namespace simple.stuffs { |
||
| 225 | component ParameterisedComponent1[T extends Number] { |
||
| 226 | |||
| 227 | provides p1: java.util.concurrent.Callable[T] |
||
| 228 | provides p2: java.util.concurrent.Callable[String] |
||
| 229 | } |
||
| 230 | |||
| 231 | component ParameterisedComponent2[T1,T2 extends Number] { |
||
| 232 | |||
| 233 | part p1: ParameterisedComponent1[T2] { |
||
| 234 | |||
| 235 | } |
||
| 236 | |||
| 237 | part p2: ParameterisedComponent1[Integer] { |
||
| 238 | |||
| 239 | } |
||
| 240 | |||
| 241 | } |
||
| 242 | } |
||
| 243 | </pre> |