Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced CORBA Programming wit C++ - M. Henning, S. Vinoski.pdf
Скачиваний:
65
Добавлен:
24.05.2014
Размер:
5 Mб
Скачать

IT-SC book: Advanced CORBA® Programming with C++

in LifespanPolicyValue

value

);

 

IdAssignmentPolicy

 

create_id_assignment_policy(

value

in IdAssignmentPolicyValue

);

 

IdUniquenessPolicy

 

create_id_uniqueness_policy(

value

in IdUniquenessPolicyValue

);

 

ImplicitActivationPolicy

 

create_implicit_activation_policy(

 

in ImplicitActivationPolicyValue value

 

);

 

RequestProcessingPolicy

 

create_request_processing_policy(

value

in RequestProcessingPolicyValue

);

 

ServantRetentionPolicy

 

create_servant_retention_policy(

value

in ServantRetentionPolicyValue

);

 

ThreadPolicy

 

create_thread_policy(

value

in ThreadPolicyValue

);

 

};

 

};

 

Each factory operation works in the same way: you pass the desired value for the new policy object, and the operation returns the object's reference. Eventually, you must call the destroy operation (inherited from the base CORBA::Policy interface) on the returned object to clean it up. Typically, you create the necessary policy objects and pass them in a PolicyList to the POA creation function. The POA creation operation copies the policies, and this means that you can invoke destroy on your copies immediately after the POA creation operation returns.

11.5 POA Creation

To put POA policies into effect, you apply them to POAs at creation time. You create a POA by invoking the create_POA operation on another POA. Because all server applications have a Root POA, its create_POA operation serves as the starting point for creating other POAs.

393

IT-SC book: Advanced CORBA® Programming with C++

A POA created using another POA becomes a child POA of the creating POA. Note, however, that this has no effect on the policies of the child POA. Policies are not inherited from parent POAs. Instead, default values are applied if no policy values are passed to the create_POA operation.

The signature of the create_POA operation is as follows:

module PortableServer {

interface POAManager;

 

exception AdapterAlreadyExists {};

 

exception InvalidPolicy {

 

unsigned short index;

 

};

 

interface POA {

 

POA create_POA(

adapter_name,

in string

in POAManager

manager,

in CORBA::PolicyList policies

 

) raises(AdapterAlreadyExists, InvalidPolicy); // ...

};

};

The important points to note about these IDL definitions are as follows:

As we describe in Section 9.2, a POAManager allows applications to control the flow of requests into a POA. The POAManager is forward-declared in this example only to keep our focus on create_POA. It is described fully in Section 11.10.

The create_POA operation takes three arguments. The first one is the name of the POA being created. The second one is a reference to the POAManager that controls the request flow for the POA being created. If the POAManager argument is nil, a new POAManager will be created for the new POA. The final argument is the list of policies to apply to the newly created POA.

The create_POA operation can raise two exceptions. It raises the AdapterAlreadyExists exception if create_POA is given the name of a POA that was already used for another child POA of the same parent POA. If the policy list contains policies that are unknown or inconsistent, the create_POA operation raises the InvalidPolicy exception, setting the index member of the exception to the index of the offending policy in the PolicyList sequence.

We create a child POA of the Root POA this way:

// Initialize the ORB.

CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

// Get a reference to the Root POA. CORBA::Object_var obj =

orb->resolve_initial_references("RootPOA"); PortableServer::POA_var root_poa =

PortableServer::POA::_narrow(obj); assert(!CORBA::is_nil(root_poa));

394

IT-SC book: Advanced CORBA® Programming with C++

//Create empty PolicyList for child POA. CORBA::PolicyList policy_list;

//Invoke create_POA to create the child. PortableServer::POA_var child_poa =

root_poa->create_POA("child", PortableServer::POAManager::_nil(), policy_list);

The first part of this example shows the normal sequence of invocations we make to initialize the ORB and get a reference to the Root POA. We then create a CORBA::PolicyList sequence, which, like all sequences, is empty when you se the default constructor. Finally, we invoke create_POA on the Root POA, passing the string "child" for the name of the new POA, a nil POAManager reference, and our empty policy list. Assuming that a POA named "child" does not already exist as a child of the Root POA, create_POA returns an object reference to our new POA.

Naturally, create_POA can be invoked on any POA. Calling it on a child POA of the Root POA, for example, produces a grandchild of the Root POA. In the following example we create a hierarchy of POAs:

//Set up a nil POAManager reference

//to pass to each create_POA call. PortableServer::POAManager_var nil_mgr =

PortableServer::POAManager::_nil();

//Create POA A, child of the Root POA. PortableServer::POA_var poa_A =

root_poa->create_POA("A", nil_mgr, policy_list);

//Create POA B, child of the Root POA. PortableServer::POA_var poa_B =

root_poa->create_POA("B", nil_mgr, policy_list);

//Create POA C, child of the Root POA. PortableServer::POA_var poa_C =

root_poa->create_POA("C", nil_mgr, policy_list);

//Create POA D, child of POA B. PortableServer::POA_var poa_D =

poa_B->create_POA("D", nil_mgr, policy_list);

//Create POA E, child of POA D. PortableServer::POA_var poa_E =

poa_D->create_POA("E", nil_mgr, policy_list);

We first create a nil POAManager reference to pass to each create_POA invocation, and we assume we are passing the same empty policy list we created in the preceding example. We then create POAs A, B, and C as children of the Root POA. After that we create POA D as a child of POA B, and finally we create POA E as a child of POA D.

395

IT-SC book: Advanced CORBA® Programming with C++

This sequence of create_POA invocations results in the POA hierarchy shown in

Figure 11.6.

Figure 11.6 An example POA hierarchy.

Our example shows the mechanics of creating POAs, but it is somewhat unrealistic in that it does not vary the policies of each POA. One of the main reasons that applications create and use multiple POAs is to assign different policies to each one. Because the Root POA supports only transient objects, a common policy to apply to a new POA is to give it the PERSISTENT life span policy:

//Create a PERSISTENT LifespanPolicy object. PortableServer::LifespanPolicy_var lifespan =

root_poa->create_lifespan_policy(PortableServer::PERSISTENT);

//Create PolicyList.

CORBA::PolicyList policy_list; policy_list.length(1); policy_list[0] =

PortableServer::LifespanPolicy::_duplicate(lifespan);

//Create the child POA. PortableServer::POA_var child =

root_poa->create_POA("child", nil_mgr, policy_list);

//Destroy our LifespanPolicy object.

lifespan->destroy();

We first use the create_lifespan_policy operation of the Root POA to create a LifespanPolicy object, passing PERSISTENT as the value for the policy. Remember, any POA can serve as a factory for policy objects, and the created policy objects are in no way tied to the POA that creates them. Next, we create a single-element policy list and copy our reference to our LifespanPolicy object into it. We then invoke create_POA on the Root POA, passing to it the name of the new POA, our nil POAManager reference from our earlier example, and our policy list containing a reference to our PERSISTENT life span policy object. Finally, we invoke destroy on

396