18.3.1 動的リクエスト用オブジェクトの設計例
コードサンプル18-3および18-4に,DSIを使用してインプリメントするC++およびJavaのAccountImplクラスの宣言を示します。これは,invokeメソッドを宣言するDynamicImplementationクラスから派生します。VisiBroker ORBは,そのinvokeメソッドを呼び出して,クライアントオペレーション要求をServerRequestオブジェクトの形でインプリメンテーションに引き渡します。
コードサンプル18-3にAccountクラスコンストラクタと_primary_interface関数を示します。
- コードサンプル18-3 dynamicから派生するAccountImplクラスの例(C++)
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クラスコンストラクタの例を示します。
- コードサンプル18-4 Dynamicから派生するAccountImplクラスの例(Java)
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オブジェクトの形でインプリメンテーションに引き渡します。
- コードサンプル18-5 Dynamicから派生するAccountManagerImplクラスの例(C++)
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); } };
- コードサンプル18-6 Dynamicから派生するAccountManagerImplクラスの例(Java)
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; }