Hitachi

VisiBroker Version 5 Borland(R) Enterprise Server VisiBroker(R) デベロッパーズガイド


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;
}