Overview of connector generation
The main idea of the approach used for connector generation is to use two connector models – one to carry a high-level human-oriented connector specification, and the other (being low-level and machine oriented) to serve as a basis for code generation. The high-level connector specification is in our approach represented as name-value pairs describing a communication style (e.g., synchronous method invocation, asynchronous messaging, point-to-point streaming, distributed shared memory – blackboard, etc.) and other non-functional properties (e.g., encryption, monitoring, etc.). The low-level connector description is called connector configuration. It provides an architectural description of a connector directly stating what code fragments and how to compose together to form the connector implementation.
To capture a connector structure, we use an architectural connector model, which views a connector as composed of rather simplistic components called elements (see the figure below). Elements can either primitive (i.e., implemented directly in a particular programming language) or composite (i.e., described by an architecture specifying the first-level of nesting). The low-level connector configuration is in fact a vertical composition of the elements so that in leaves there are primitive elements only.
Generation process overview
The whole generation process is depicted in the figure below. It consists of two steps. In the first step, the high-level connector specification is transformed to a low-level connector configuration using the knowledge of deployment dock capabilities and the architectural connector model (which describes different variants for connector architectures and elements). As a second step, connector code is generated according to the low-level configuration.
The first step (transformation of the high-level specification to the low-level connector configuration) is carried out by an architecture resolver written in Prolog. (In our implementation we use tuProlog, since it is light-weighted and it is entirely written in Java.) The goal is basically to find a connector configuration which satisfies the following three conditions.
- High-level specification consistency. The connector configuration complies to the high-level connector specification in the terms of communication style, NFPs, prescribed connector units and port signatures on the units. In other words, this conditions assures that the connector implements the expected funtionality.
- Deployment consistency. This condition assures that the generated connector units will be able to run in target deployment docks. It means that all requirements on libraries installed on a target dock, operating system, etc. will be satisfied.
- Cooperation consistency. The connector is composed of elements. Not necessarily all assignments of element implementations yield a working connector. Obviously, it is not possible to combine for example RMI skeleton with CORBA stub. This condition assures that the elements in the connector configuration are able to cooperate.
In the second step, the connector code is generated based on the connector configuration. It typically comprises generation of source code, its compiling and packaging. The process is complicated by the need of generating code for different component systems utilizing different language and type-conventions.
The approach is described in more detail in the doctoral thesis. The thesis additionally proposes a platform independent model of connector runtime environment and its reifications for SOFA and Fractal component systems. The thesis also shows how to integrate connectors and their generation to the deployment process driven by OMG D&C specification.