Разработка клиента

Вадим Годунко <vgodunko@gmail.com>, 2007 г.

Теперь пора приступить к разработке клиента. В связи с неизменностью интерфейса сервера клиентская программа сразу представлена в полном объёме. При запуске программа клиент получает в командной строке объектную ссылку фабрики и объектную ссылку поисковика. Для удобства проведения эксперементов программа имет простейшее меню.

Далее приводится исходный текст программы клиента с необходимыми комментариями.

with Ada.Characters.Conversions;
with Ada.Command_Line;
with Ada.Integer_Wide_Text_IO;
with Ada.Strings.Wide_Unbounded.Wide_Text_IO;
with Ada.Wide_Text_IO;

with CORBA.ORB;

with PolyORB.Setup.Client;
--  Конфигурирование PolyORB для работы в режиме клиента.

with Users.User;
with Users.UserFactory; -- .Helper;
with Users.UserFinder; -- .Helper;

procedure Client is
begin
   --  Инициализация ORB.

   declare
      Argv : CORBA.ORB.Arg_List := CORBA.ORB.Command_Line_Arguments;

   begin
      CORBA.ORB.Init (CORBA.ORB.To_CORBA_String ("ORB"), Argv);
   end;

   if Ada.Command_Line.Argument_Count /= 2 then
      Ada.Wide_Text_IO.Put_Line ("client <factory_ior> <finder_ior>");

      return;
   end if;

   declare
      Factory : Users.UserFactory.Ref;
      Finder  : Users.UserFinder.Ref;
      Current : Users.User.Ref;

      procedure Create_New_User is
         Name    : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
         Surname : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;

      begin
         --  Ввод имени и фамилии пользователя.

         Ada.Wide_Text_IO.Put ("Name: ");
         Ada.Wide_Text_IO.Flush;
         Ada.Strings.Wide_Unbounded.Wide_Text_IO.Get_Line (Name);
         Ada.Wide_Text_IO.Put ("Surname: ");
         Ada.Wide_Text_IO.Flush;
         Ada.Strings.Wide_Unbounded.Wide_Text_IO.Get_Line (Surname);

         --  Создание нового объекта.

         Current :=
           Users.UserFactory.create
            (Factory,
             CORBA.To_CORBA_Wide_String
              (Ada.Strings.Wide_Unbounded.To_Wide_String (Name)),
             CORBA.To_CORBA_Wide_String
              (Ada.Strings.Wide_Unbounded.To_Wide_String (Surname)));
      end Create_New_User;

      procedure Save_IOR is
         File_Name : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
         File      : Ada.Wide_Text_IO.File_Type;

      begin
         --  Проверка наличия текущей объектной ссылки.

         if Users.User.Is_Nil (Current) then
            Ada.Wide_Text_IO.Put_Line ("ERROR: No IOR in buffer");
         end if;

         --  Ввод имени файла.

         Ada.Wide_Text_IO.Put ("File name: ");
         Ada.Wide_Text_IO.Flush;
         Ada.Strings.Wide_Unbounded.Wide_Text_IO.Get_Line (File_Name);

         --  Создание файла и сохранение в нём объектной ссылки.

         Ada.Wide_Text_IO.Create
          (File,
           Ada.Wide_Text_IO.Out_File,
           Ada.Characters.Conversions.To_String
            (Ada.Strings.Wide_Unbounded.To_Wide_String (File_Name)));
         Ada.Wide_Text_IO.Put_Line
          (File,
           Ada.Characters.Conversions.To_Wide_String
            (CORBA.To_Standard_String
              (CORBA.ORB.Object_To_String (Current))));
         Ada.Wide_Text_IO.Close (File);
      end Save_IOR;

      procedure Load_IOR is
         File_Name : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
         File      : Ada.Wide_Text_IO.File_Type;
         Image     : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;

      begin
         --  Ввод имени файла.

         Ada.Wide_Text_IO.Put ("File name: ");
         Ada.Wide_Text_IO.Flush;
         Ada.Strings.Wide_Unbounded.Wide_Text_IO.Get_Line (File_Name);

         --  Открытие файла и загрузка из него объектной ссылки.

         Ada.Wide_Text_IO.Open
          (File,
           Ada.Wide_Text_IO.In_File,
           Ada.Characters.Conversions.To_String
            (Ada.Strings.Wide_Unbounded.To_Wide_String (File_Name)));
         Ada.Strings.Wide_Unbounded.Wide_Text_IO.Get_Line (File, Image);
         Ada.Wide_Text_IO.Close (File);

         --  Создание объектной ссылки по её образу.

         CORBA.ORB.String_To_Object
          (CORBA.To_CORBA_String
            (Ada.Characters.Conversions.To_String
              (Ada.Strings.Wide_Unbounded.To_Wide_String (Image))),
           Current);
      end Load_IOR;

      procedure Show_Attributes is
      begin
         --  Проверка наличия текущей объектной ссылки.

         if Users.User.Is_Nil (Current) then
            Ada.Wide_Text_IO.Put_Line ("ERROR: No IOR in buffer");

            return;
         end if;

         --  Получение и отображение значений атрибутов.

         Ada.Wide_Text_IO.Put_Line
          ("Name: '"
             & CORBA.To_Standard_Wide_String (Users.User.Get_name (Current))
             & "'");
         Ada.Wide_Text_IO.Put_Line
          ("Surname: '"
             & CORBA.To_Standard_Wide_String (Users.User.Get_surname (Current))
             & "'");
      end Show_Attributes;

      procedure Search_By_Name is
         Name  : Ada.Strings.Wide_Unbounded.Unbounded_Wide_String;
         Found : Users.UserSequence;
         Index : Integer;

      begin
         Ada.Wide_Text_IO.Put ("Name: ");
         Ada.Wide_Text_IO.Flush;
         Ada.Strings.Wide_Unbounded.Wide_Text_IO.Get_Line (Name);

         Found :=
           Users.UserFinder.by_name
            (Finder,
             CORBA.To_CORBA_Wide_String
              (Ada.Strings.Wide_Unbounded.To_Wide_String (Name)));

         Ada.Wide_Text_IO.Put_Line
          ("Found" & Integer'Wide_Image (Users.Length (Found)));  

         for J in 1 .. Users.Length (Found) loop
            Ada.Wide_Text_IO.Put_Line
             (Integer'Wide_Image (J)
                & ": '"
                & CORBA.To_Standard_Wide_String
                   (Users.User.Get_name
                     (Users.User.Convert_Forward.To_Ref
                       (Users.Get_Element (Found, J))))
                & "', '"
                & CORBA.To_Standard_Wide_String
                   (Users.User.Get_surname
                     (Users.User.Convert_Forward.To_Ref
                       (Users.Get_Element (Found, J))))
                & "'");
         end loop;

         Ada.Wide_Text_IO.Put ("Selection (0 - ignore): ");
         Ada.Wide_Text_IO.Flush;
         Ada.Integer_Wide_Text_IO.Get (Index);
         Ada.Wide_Text_IO.Skip_Line;

         if Index in 1 .. Users.Length (Found) then
            Current :=
              Users.User.Convert_Forward.To_Ref
               (Users.Get_Element (Found, Index));
         end if;
      end Search_By_Name;

   begin
      --  Преобразование параметров командной строки в объектные ссылки.

      CORBA.ORB.String_To_Object
       (CORBA.To_CORBA_String (Ada.Command_Line.Argument (1)), Factory);

      CORBA.ORB.String_To_Object
       (CORBA.To_CORBA_String (Ada.Command_Line.Argument (2)), Finder);

      --  Цикл обработки ввода пользователя.

      loop
         declare
            Choice : Natural;

         begin
            Ada.Wide_Text_IO.New_Line;
            Ada.Wide_Text_IO.Put_Line ("Menu:");
            Ada.Wide_Text_IO.Put_Line (" 1: Create new user");
            Ada.Wide_Text_IO.Put_Line (" 2: Save IOR");
            Ada.Wide_Text_IO.Put_Line (" 3: Load IOR");
            Ada.Wide_Text_IO.Put_Line (" 4: Show attributes");
            Ada.Wide_Text_IO.Put_Line (" 5: Search by name");
            Ada.Wide_Text_IO.New_Line;
            Ada.Wide_Text_IO.Put_Line (" 0: Exit");
            Ada.Wide_Text_IO.New_Line;

            Ada.Wide_Text_IO.Put ("Choice: ");
            Ada.Wide_Text_IO.Flush;
            Ada.Integer_Wide_Text_IO.Get (Choice);
            Ada.Wide_Text_IO.Skip_Line;

            case Choice is
               when 0 =>
                  exit;

               when 1 =>
                  Create_New_User;

               when 2 =>
                  Save_IOR;

               when 3 =>
                  Load_IOR;

               when 4 =>
                  Show_Attributes;

               when 5 =>
                  Search_By_Name;

               when others =>
                  null;
            end case;

            --  Вывод объектной ссылки нового пользователя.
           
            if not Users.User.Is_Nil (Current) then
               Ada.Wide_Text_IO.Put_Line
                ("Current user's IOR: '"
                   & Ada.Characters.Conversions.To_Wide_String
                      (CORBA.To_Standard_String
                        (CORBA.ORB.Object_To_String (Current)))
                   & "'");
            end if;
         end;
      end loop;
   end;
end Client;