• No results found

Suppressing generated implementation

3.3 Language Mapping

3.3.1 Overview

This part describes the language mapping for CORBA Components and defines interfaces that are used to implement components and homes. The language mapping, like the mapping for the client side, is based on equivalent IDL. For components and homes, local interfaces are defined. The user then implements these local interfaces using existing language mapping rules.

There are two strategies for implementing a component, coined monolithic and locator. In the monolithic strategy, the user implements all attributes, supported interfaces, and event consumers in a single executor interface. In the locator strategy, the user implements a locator, and the container uses this locator to retrieve references to executors for each port of a component. The decision which strategy is being used is made by the home, which can return a reference to either the monolithic or to the locator.

It is expected that the monolithic strategy is more simple to use and that it is sufficient for most use cases, while the locator strategy gives the user even more control over the life cycle of each executor.

Interfaces are designated internal or callback. Callback interfaces are implemented by the user and called by the container, while internal interfaces are provided by the container.

Some callback interfaces may be optionally implemented by the user. In order to optionally implement an interface, the user must define an interface, in IDL, that inherits both the base interface and the optional interface. For example, to inherit the optional SessionSynchronization interface in the implementation of a Bank component, the user would declare a new local interface, as shown below. local interface MyBank :

Components::SessionSynchronization, CCM_Bank { };

Optional interfaces are used by services that require the componentÕs cooperation (and therefore callback hooks). To determine whether an implementation supports an optional interface, the container narrows the object reference to that interface. Internal interfaces are used by the container and various services to provide runtime information to the component. The component accesses internal interfaces through the context reference that it acquires through the set_session_context operation.

Details about existing internal and callback interfaces can be found in the Container Programming Model chapter. Some of those interfaces are forward-referenced in this section.

3.3.2 Common Interfaces

EnterpriseComponent is an empty callback interface that serves as common base for all component implementations, whether monolithic or locator-based.

module Components {

local interface EnterpriseComponent {}; };

Note Ð The EnterpriseComponent interface is also defined in the Container Programming Model chapter.

The ExecutorLocator interface is a callback interface that is used for the locator implementation strategy.

module Components {

local interface ExecutorLocator : EnterpriseComponent { Object obtain_executor (in string name)

raises (CCMException);

void release_executor (in Object exc) raises (CCMException);

void configuration_complete() raises (InvalidConfiguration); };

};

If a home, in creating a component, returns an ExecutorLocator, the container will invoke its obtain_executor operation prior to each invocation to retrieve the implementation for a port. The port name, given in the name parameter, is the same as used in the componentÕs interface description in IDL, or the componentÕs name for the ÒmainÓ executor. The obtain_executor operation returns a local object reference of the expected type, as detailed below. The CCMException exception may be raised in case of a system error that prohibits locating the requested executor.

The release_executor operation is called by the container once the current

invocation on an executor that was obtained through the obtain_executor operation has finished. The locator can thus release any resources that were acquired as part of the obtain_executor operation.

The configuration_complete operation is called to propagate the

configuration_complete operation on the CCMObject interface to the component implementation.

Implementations of the ExecutorLocator interface for a service or session component must implement the Components::SessionComponent interface. Implementations of the ExecutorLocator interface for a process or entity component must implement the Components::EntityComponent interface.

Note Ð Object is used as the return type of the obtain_executor operation, because there is yet no IDL type for the common base of all local objects. Since local objects inherit from Object, this is not a problem.

The HomeExecutorBase interface is a common base for all home implementations. module Components {

local interface HomeExecutorBase {}; };

3.3.3 Mapping Rules

This section defines equivalent interfaces that are generated for each interface, eventtype, component, and home.

3.3.3.1 Interfaces

For each non-abstract and non-local interface, a local facet executor interface is generated. This facet executor interface has the same name as the original interface with a ÒCCM_Ó prefix, and inherits the original interface. So for an interface of name <interface name>, the facet executor interface has the following form:

local interface CCM_<interface name> : <interface name> { };

If a component provides an interface as a facet, the user implements the facet executor interface rather than the original interface in order to achieve a local implementation.

Note Ð A container implementation may choose to limit generation of facet executor interfaces to only those interfaces that are actually used as a facet.

3.3.3.2 Eventtypes

For each eventtype, a local consumer executor interface is generated. For an eventtype <eventtype name>, a local interface with the same name, but with a ÒCCM_Ó prefix and a postfix of ÒConsumerÓ is generated. This interface has a single push operation with no result, and the eventtype as a single in parameter:

local interface CCM_<eventtype name>Consumer {

void push (in <eventtype name> ev); };

3.3.3.3 Components

A component maps to three local interfaces; two of them are callback interfaces, and one is an internal interface. The monolithic executor callback interface is for use in monolithic implementations, the main executor callback interface is for use in locator- based implementations. Both callback interfaces inherit the componentÕs base and supported interfaces. They also both expose the componentÕs attributes.

In addition, the monolithic executor callback interface also contains operations for acquiring references to facets, and for consuming events - in the locator approach, these jobs are mediated by the locator.

An internal context interface is defined for each component. It is implemented by the container and handed to the component as session or entity context. The context interface contains component-specific runtime information (e.g., for pushing events into event source ports).