Projet

Général

Profil

Actions

SpeADL Minus Java Reference » Historique » Révision 10

« Précédent | Révision 10/13 (diff) | Suivant »
Anonyme, 17/10/2014 16:24


Java for SpeADL⁻ Reference Guide

In the SpeADL⁻ reference guide we saw how one can define components and composition of components.
We now present how to implement these components in Java.

Terminology

The reader can refer to the MAY Terminology document to get an overview of the different terms used in SpeADL.

SpeADL⁻

It is needed to understand the content of the SpeADL⁻ Reference Guide before reading the current document.

Component Implementation

To implement a component, one has to extend the abstract class generated automatically by the Eclipse plugin.
For example, for the previous example simple.stuffs.MyBeautifulComponent defined in SpeADL, a Java class simple.stuffs.MyBeautifulComponent is generated (in the speadl-gen folder, different than the src folder).

It is not needed to look at the generated code to use it: when extending the class, some abstract methods will have to be implemented.

When implementing a component, one only has to take care of implementing the provided port, and can exploit the required ports without assuming anything about their implementation and who provides it.
This is one thing that makes a component fundamentally different from an object.

Special Methods to Implement

Each provided port p of interface I must be implemented by overriding a method called I make_p() which returns an instance of the implementation for the port.
This instance is used for the whole life of the component, i.e., the make_p() method is called only once to construct the port when the component is instantiated.

Each part p of component class C has a corresponding abstract method C make_p() to override and which must return an instance of an implementation of C.
The bindings and other connections inside the components are totally taken care of by the generated code and the implementation only needs what is Java-specific.

Furthermore, optionally, a method void start() can be override as explained below.

Special Methods to Exploit

The requires() method (inherited from the extended generated class) gives access to each of the required ports (e.g., requires().port()).
A port being an implementation of an interface (and not of an operation), it is then necessary to call the desired method on it (e.g., requires().port().method()).

The provided() method (inherited from the extended generated class) gives access to each of the provided ports in the same manner.

It is possible to access to the provided ports of the part from within the implementation of a composite by using the method parts() (e.g., parts().partName().portName().method()).

Examples

Implementing a component with a provided port:

package testpackage;

import my.interfaces.AnotherJavaInterface;
import simple.stuffs.MySimpleComponent;

public class MySimpleComponentImpl extends MySimpleComponent {

    @Override
    protected AnotherJavaInterface make_p1() {
        return new AnotherJavaInterface() {
            @Override
            public Integer test() {
                return 10;
            }
        };
    }

}

The same result can be obtained by implementing the port directly by the component implementation as follow:

public class MySimpleComponentImpl extends MySimpleComponent implements AnotherJavaInterface {

    @Override
    public Integer test() {
        return 10;
    }

    @Override
    protected AnotherJavaInterface make_p1() {
        return this;
    }
}

Exploiting a required port:

package testpackage;

import my.interfaces.AJavaInterface;
import simple.stuffs.MyBeautifulComponent;

public class MyComponentImpl extends MyBeautifulComponent {

    @Override
    protected AJavaInterface make_portName() {
        return new AJavaInterface() {
            @Override
            public String aMethod(Integer param1) {
                return "" + param1 + " and " + requires().anotherPortName().test();
            }
            @Override
            public String anotherMethod() {
                return "plop";
            }
        };
    }
}

Implementing a component with parts, calling a part's provided port:

public class CompositeCompImpl extends MyCompositeComponent {

    @Override
    protected MySimpleComponent make_s() {
        return new MySimpleComponentImpl();
    }

    @Override
    protected AnotherJavaInterface make_p1() {
        return new AnotherJavaInterface() {
            @Override
            public Integer test() {
                return parts().s().p1().test();
            }
        };
    }

    @Override
    protected MyBeautifulComponent make_b1() {
        return new MyComponentImpl();
    }

    @Override
    protected MyBeautifulComponent make_b2() {
        return new MyComponentImpl();
    }

    @Override
    protected MyBeautifulComponent make_b3() {
        return new MyComponentImpl();
    }
}

Component Instantiation

In order to instantiate a component from Java, one need an instance of an implementation of the component and to call the newComponent() method (present in the generated class) to get an instance of the component.

Details

Only component without required port can be manually instantiated from Java: if a component has required ports, it must be composed with other components in a composite component.

Once we have an instance of a component, we can call the methods of its provided ports.

The same applies for composite components, the instantiation of the part of a composite is done automatically by the generated code.

Example

MySimpleComponent.Component c = new MySimpleComponentImpl().newComponent();
System.out.println(c.p1().test());

Component Initialisation

When the implementation of a component is instantiated (before calling newComponent()), its constructor is of course called but the component itself is not yet initialised: in particular its provided required ports and parts can't be called at that time.

Details

In order to do some initialisation at the instantiation of a component (during the call to newComponent()), one can override the void start() method of the extended abstract class.

Example

public class MySimpleComponentImpl extends MySimpleComponent {

    @Override
    protected AnotherJavaInterface make_p1() {
        return new AnotherJavaInterface() {
            @Override
            public Integer test() {
                return 10;
            }
        };
    }

    @Override
    protected void start() {
        // do some initialisation using the requires() or the parts(), create a GUI, etc...
    }
}

Lifecycle of Component Initialisation at Instantiation

When newComponent() is called on a component implementation, this is what happens:
  1. The component is instantiated (see below).
  2. The instance is started (see below).

Component Instantiation

  1. For each part partX in the order of declaration
    1. The implementation is instantiated with the make_partX() method.
    2. A component is instantiated from the implementation following the current procedure.
  2. For each provided port portX in the order of declaration (starting with the super-component in case of specialisation)
    1. The interface implementation is instantiated with the make_portX() method.

Component Instance Start

  1. For each part partX in the order of declaration
    1. The part is started following the current procedure.
  2. The implementation start() method is called.

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