コードサンプル18-3および18-4に,DSIを使用してインプリメントするC++およびJavaのAccountImplクラスの宣言を示します。これは,invokeメソッドを宣言するDynamicImplementationクラスから派生します。VisiBroker ORBは,そのinvokeメソッドを呼び出して,クライアントオペレーション要求をServerRequestオブジェクトの形でインプリメンテーションに引き渡します。
コードサンプル18-3にAccountクラスコンストラクタと_primary_interface関数を示します。
class AccountImpl :
public PortableServer::DynamicImplementation ,
public virtual PortableServer::RefCountServantBase{
public:
AccountImpl(PortableServer::Current_ptr current,
PortableServer::POA_ptr poa)
: _poa_current(PortableServer::Current::_
duplicate(current)), _poa(poa)
{}
CORBA::Object_ptr get(const char *name) {
CORBA::Float balance;
// Check if account exists
if (!_registry.get(name, balance)) {
// simulate delay while creating new account
VISPortable::vsleep(3);
// Make up the account's balance,
between 0 and 1000 dollars
balance = abs(rand()) % 100000 / 100.0;
// Print out the new account
cout << "Created " << name << "'s account: "
<< balance << endl;
_registry.put(name, balance);
}
// Return object reference
PortableServer::ObjectId_var accountId =
PortableServer::string_to_ObjectId(name);
return _poa->create_reference_with_id(
accountId, "IDL:Bank/Account:1.0");
}
private:
AccountRegistry _registry;
PortableServer::POA_ptr _poa;
PortableServer::Current_var _poa_current;
CORBA::RepositoryId _primary_interface(
const PortableServer::ObjectId& oid,
PortableServer::POA_ptr poa) {
return CORBA::string_dup(
(const char *)"IDL:Bank/Account:1.0");
};
void invoke(CORBA::ServerRequest_ptr request) {
// Get the account name from the object id
PortableServer::ObjectId_var oid =
_poa_current->get_object_id();
CORBA::String_var name;
try {
name = PortableServer::ObjectId_to_string(oid);
} catch (const CORBA::Exception& e) {
throw CORBA::OBJECT_NOT_EXIST();
}
// Ensure that the operation name is correct
if (strcmp(request->operation(), "balance") != 0) {
throw CORBA::BAD_OPERATION();
}
// Find out balance and fill out the result
CORBA::NVList_ptr params = new CORBA::NVList(0);
request->arguments(params);
CORBA::Float balance;
if (!_registry.get(name, balance))
throw CORBA::OBJECT_NOT_EXIST();
CORBA::Any result;
result <<= balance;
request->set_result(result);
cout << "Checked " << name << "'s balance: "
<< balance << endl;
}
};
コードサンプル18-4にAccountクラスコンストラクタの例を示します。
import java.util.*;
import org.omg.PortableServer.*;
public class AccountImpl extends DynamicImplementation {
public AccountImpl(org.omg.CORBA.ORB orb, POA poa) {
_orb = orb;
_poa = poa;
}
public synchronized org.omg.CORBA.Object get(String name) {
org.omg.CORBA.Object obj;
// Check if account exists
Float balance = (Float)_registry.get(name);
if (balance == null) {
// simulate delay while creating new account
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
// Make up the account's balance, between 0 and 1000 dollars
balance = new Float(Math.abs(_random.nextInt())
% 100000 / 100f);
// Print out the new account
System.out.println("Created " + name + "'s account: " +
balance.floatValue());
_registry.put(name, balance);
}
// Return object reference
byte[ ] accountId = name.getBytes();
try {
obj = _poa.create_reference_with_id(accountId,
"IDL:Bank/Account:1.0");
} catch (org.omg.PortableServer.POAPackage.WrongPolicy e) {
throw new org.omg.CORBA.INTERNAL(e.toString());
}
return obj;
}
public String[ ] _all_interfaces(POA poa, byte[ ] objectId) {
return null; }
public void invoke(org.omg.CORBA.ServerRequest request) {
Float balance;
// Get the account name from the object id
String name = new String(_object_id());
// Ensure that the operation name is correct
if (!request.operation().equals("balance")) {
throw new org.omg.CORBA.BAD_OPERATION();
}
// Find out balance and fill out the result
org.omg.CORBA.NVList params = _orb.create_list(0);
request.arguments(params);
balance = (Float)_registry.get(name);
if (balance == null) {
throw new org.omg.CORBA.OBJECT_NOT_EXIST();
}
org.omg.CORBA.Any result = _orb.create_any();
result.insert_float(balance.floatValue());
request.set_result(result);
System.out.println("Checked " + name + "'s balance: " +
balance.floatValue());
}
private Random _random = new Random();
static private Hashtable _registry = new Hashtable();
private POA _poa;
private org.omg.CORBA.ORB _orb;
}
コードサンプル18-5および18-6に,DSIを使用してインプリメントする必要のあるAccountManagerImplクラスのインプリメンテーションを示します。これは,invokeメソッドを宣言するDynamicImplementationクラスからも派生します。VisiBroker ORBは,そのinvokeメソッドを呼び出して,クライアントオペレーション要求をServerRequestオブジェクトの形でインプリメンテーションに引き渡します。
class AccountManagerImpl
: public PortableServer::DynamicImplementation,
public virtual PortableServer::RefCountServantBase {
public:
AccountManagerImpl(AccountImpl* accounts)
{ _accounts = accounts; }
CORBA::Object_ptr open(const char* name) {
return _accounts->get(name);
}
private:
AccountImpl* _accounts;
CORBA::RepositoryId _primary_interface
(const PortableServer::ObjectId& oid,
PortableServer::POA_ptr poa) {
return CORBA::string_dup((const char *)
"IDL:Bank/AccountManager:1.0");
};
void invoke(CORBA::ServerRequest_ptr request) {
// Ensure that the operation name is correct
if (strcmp(request->operation(), "open") !=0)
throw CORBA::BAD_OPERATION();
// Fetch the input parameter
char *name = NULL;
try {
CORBA::NVList_ptr params = new CORBA::NVList(1);
CORBA::Any any;
any <<= (const char*) "";
params->add_value("name", any, CORBA::ARG_IN);
request->arguments(params);
*(params->item(0)->value()) >>= name;
} catch (const CORBA::Exception& e) {
throw CORBA::BAD_PARAM();
}
// Invoke the actual implementation and
// fill out the result
CORBA::Object_var account = open(name);
CORBA::Any result;
result <<= account;
request->set_result(result);
}
};
import org.omg.PortableServer.*;
public class AccountManagerImpl extends DynamicImplementation {
public AccountManagerImpl(org.omg.CORBA.ORB orb, AccountImpl
accounts) { _orb =orb; _accounts =accounts;
}
public synchronized org.omg.CORBA.Object open(String name) {
return _accounts.get(name);
}
public String[ ] _all_interfaces(POA poa, byte[ ] objectId)
{ return null; }
public void invoke(org.omg.CORBA.ServerRequest request) {
// Ensure that the operation name is correct
if (!request.operation().equals("open")) {
throw new org.omg.CORBA.BAD_OPERATION();
}
// Fetch the input parameter
String name = null;
try {
org.omg.CORBA.NVList params = _orb.create_list(1);
org.omg.CORBA.Any any = _orb.create_any();
any.insert_string(new String(""));
params.add_value("name", any, org.omg.CORBA.ARG_IN.value);
request.arguments(params);
name = params.item(0).value().extract_string();
} catch (Exception e) {
throw new org.omg.CORBA.BAD_PARAM();
}
// Invoke the actual implementation and fill out the result
org.omg.CORBA.Object account = open(name);
org.omg.CORBA.Any result = _orb.create_any();
result.insert_Object(account);
request.set_result(result);
}
private AccountImpl _accounts;
private org.omg.CORBA.ORB _orb;
}