Proxy home
3.2.8 Relationship between Home Executor and Abstract Storage Home When a composition specifies managed storage, the relationship between the home
3.2.8.2 Implicit delegation of home operations
When a composition specifies managed storage, finder operations can be implemented in terms of finder operations on the abstract storage home to which the home executor is bound.
¥
The find_by_primary_key operation uses thefind_ref_by_matching_key_name operation on the abstract storagehome. The returned storage reference is used to create an object reference for the component and returned to the invoking client.
¥
Destruction operations delegate to destroy_object operations on the reference. The validity of these implementation semantics are predicated on the following assumptions:¥
The initial state of the storage object created by the storage home constitutes a valid initial state for the component.¥
All of the persistent state of the component is defined on (or reachable from) the storage object whose PID is associated with the component instance.¥
The executor is monolithic, not segmented. Home operations can also be delegated to abstract storage homes when the executor is segmented, but the process is slightly more complex, and is discussed in full in Section 3.2.9.1, ÒSegmented executors,Ó on page 3-27.If these assumptions do not hold (in particular, either of the first two), the component implementor can provide custom implementations of one or more home operations to accommodate the implementation requirements.
The following example extends the previous example to illustrate managed storage and storage home delegation. The example highlights differences from the previous, and does not repeat elements that are identical: --- // Example 2
//
// USER-SPECIFIED IDL //
module LooneyToons { // IDL
... identical to previous example, except for the addition of the primary key:
Table 3-1 Delegation of finder operations to finder operations on the bound abstract storagehome
home operation abstract storagehome operation component find_by_primary_key (key) ref<X>
find_ref_by_matching_key_name (matching_key)
public string name;
};
home ToonTown manages Toon primarykey EpisodeName {
}; };
---
Note Ð Issue 5499
The CIDL now defines an abstract storage types, and an abstract storage homes, and a catalog. The composition binds :
--- // Example 2 // // USER-SPECIFIED CIDL // import ::LooneyToons; module MerryMelodies {
abstract storagetype ToonState {
state LooneyToons::EpisodeName episode_name; state string name;
state unsigned long time_flown; state LooneyToons::Bird last_bird_eaten;
};
abstract storagehome ToonStateHome of ToonState
{
key episode_name;
factory create(episode_name);
};
catalog ToonCatalog {
provides ToonStateHome TSHome;
};
// this is the composition:
composition entity ToonImpl {
uses catalog { ToonCatalog store; };
home executor ToonTownImpl {
implements LooneyToons::ToonTown { ; bindsTo store.TSHomeToonStateHome; manages ToonEntityImpl; }; }; }; --- In this example, the composition binds the component home ToonTown to the abstract storage home ToonStateHome, and thus, implicitly binds the component type Toon to the abstract storage type ToonState. Note that the primary key (if any) in the home must match a key in the abstract stor-
age home. As will be seen later in the CIDL grammar specification, the keyword entity in the implementation binding declaration specifies a par- ticular lifecycle model for the resulting implementation.
This CIDL specification would cause the generation of the following pro- gramming objects:
¥ The skeleton for the component executor ToonEntityImpl
¥ The implementation of the home executor ToonTownImpl
¥ The incarnation interface for the abstract storage type ToonState
Note Ð Issue 5499
¥ The interface for the abstract storage home ToonStateHome.
¥ The interface for the catalog ToonCatalog.
Note that the complete implementation of the home executor may not be able to be generated in some cases, e.g., when no abstract storage type is declared or when user-defined operations with arbitrary signatures appear on the component home definition.
Note also that the implementations of the storage-related interfaces Toon- State and ToonStateHome are not necessarily provided by the same product that generates the component implementation skeletons. The CIF is specifically designed to decouple the executor implementation from the storage implementation, so that these capabilities may be provided by dif- ferent products. A component-enabled ORB product is only required to generate the programming interfaces for the abstract storage type and homes through which the executor implementation will interact with one or more storage mechanisms. The implementations of these interfaces may be supplied separately, perhaps deferred until run-time.
The interfaces generated from the IDL are identical, with the exception of the addition of the primary key:
--- // Example 2
//
// GENERATED FROM IDL SPECIFICATION: //
package LooneyToons;
import org.omg.Components.*;
... same as previous except for the following: public interface ToonTownImplicitOperations {
Toon create(LooneyToons.EpisodeName key) throws DuplicateKey, InvalidKey; Toon find_by_primary_key
(LooneyToons.EpisodeName key) throws UnknownKey, InvalidKey;
LooneyToons.EpisodeName
get_primary_key(Toon comp); }
public interface ToonTownOperations extends ToonTownExplicitOperations,
ToonTownExplicitOperations {}
--- The abstract storage type ToonState results in the generation of the follow- ing incarnation interfaces:
--- // Example 2
//
// GENERATED FROM CIDL SPECIFICATION: //
package MerryMelodies;
import org.omg.CosPersistentState.*; import LooneyToons.*;
public interface ToonState extends StorageObject { public string name();
public void name (String val); public long time_flown();
public void time_flown (long val); public Bird last_bird_eaten();
public void last_bird_eaten (Bird val); }
The storage home ToonStateHome results in the generation of the follow- ing interface:
--- // Example 2
//
// GENERATED FROM CIDL SPECIFICATION: //
// no explicit operations public interface ToonStateHome
extends StorageHomeBase { public ToonState find_by_episode_name (EpisodeName k); public ToonStateRef find_ref_by_episode_name (EpisodeName k); } --- The ToonImpl executor skeleton class has the following form:
--- // Example 2
//
// GENERATED FROM CIDL SPECIFICATION: //
package MerryMelodies; import LooneyToons;
abstract public class ToonImpl
implements LooneyToons.ToonOperations, ExecutorSegmentBase, PersistentComponent {
// Generated implementations of operations // inherited from CCMObject and
// ExecutorSegmentBase and PersistentComponent // are omitted here.
//
// ToonImpl also provides implementations of // operations inherited from ToonState, that // delegate to a separate incarnation object: protected ToonStateIncarnation _state;
protected ToonImpl() { _state = null; }
public void set_incarnation (ToonState state) { _state = state;
}
// The following operations must be implemented // by the component developer:
abstract public BirdOperations _get_facet_tweety();
abstract public CatOperations _get_facet_sylvester(); }
--- An implementation of the home executor ToonHomeImpl is generated from the CIDL specification:
--- // Example 2
//
// GENERATED FROM CIDL SPECIFICATION: //
package MerryMelodies; import LooneyToons;
public class ToonTownImpl
implements LooneyToons.ToonTownOperations, PersistentComponent, ExecutorSegmentBase {
// Implementations of operations inherited // from PersistentComponent and
//
// ToonHomeImpl also provides implementations // of operations inherited from the component // home interface ToonTown, that delegate // designated operations on the storage home //
// values set during initialization // and activation:
protected Entity2Context _origin; protected ToonStateHome _storageHome; ...
Toon create(EpisodeName key) {
// create a storage object with the key ToonState new_state = _storageHome.create(key); // REVISIT - Bernard Normier 7/27/1999 // don’t know how to complete this method }
Toon find(EpisodeName key) {
ToonStateRef ref =
_storageHome.find_ref_by_episode_name(key); // create reference from ref
// and return , same as above... }
// and so on... }
--- The user-provided executor uses the storage accessors and mutators on the incarnation:
--- // Example 2
//
// PROVIDED BY COMPONENT PROGRAMMER: //
import LooneyToons.*; import MerryMelodies.*;
public class myToonImpl extends ToonImpl implements BirdOperations, CatOperations {
public myToonImpl() { super(); } void fly (long how_long) {
_state.timeFlown
( _state.timeFlown() + how_long); }
void eat (Bird lunch) {
_state.last_bird_eaten(lunch); }
BirdOperations get_facet_tweety() { return (BirdOperations) this; }
CatOperations get_facet_sylvester() { return (CatOperations) this; }
}