Мир ПК
.
Инфоресурсы Издания Новости ТВ Обучение События Кто есть кто Об издательстве Подписка

Мир ПК

Актуально: ИТ-решение
Семейство решений IBM Tivoli: оптимизация систем хранения данных при существенном росте их объема. Удобное управление данными и их надежная защита. Мониторинг системных ресурсов.




Alt.CW

На прошедшем в Женеве традиционном автосалоне в этом году последним писком...
В исследовательской лаборатории корпорации IBM в Цюрихе разработано миниатюрное USB-устройство,...
Исследователи из Института интегральных схем и систем им. Йозефа Фраунгофера...
Специалисты Университета штата Техас работают над миниатюрными беспроводными датчиками...


Новостная лента   

IDL–заклинания эпохи распределенных вычислений    Версия для печати


Дмитрий Рамодин

Очередное занятие мы посвятим трансляции IDL. Спецификация CORBA регламентирует, во что должен превратиться каждый элемент языка IDL в процессе его трансляции в исходные тексты на языке программирования высокого уровня. Версия 2.2 спецификации CORBA расписывает подобные соответствия для Cи, Cи++, Смолток, Кобол, Ада и Java. На этом занятии рассмотрим трансляцию в Java и постараемся иллюстрировать генерацию исходных текстов на примерах.

Комментарии

Если вы вставите комментарии в IDL-файл, то это никак не будет отражено в сгенерированных Java-файлах.

Имена

Результаты работы компилятора idltojava из Sun Java 2 и idl2java из Inprise Visbroker 3.4 могут различаться. В основном это касается добавления символов подчеркивания перед сгенерированными именами. Как говорится в спецификации, это делается для предотвращения коллизии имен. Хотя в принципе язык Java способен не допустить подобных коллизий за счет механизма пакетных имен, компилятор из Java 2 добавит символ ‘_’, руководствуясь девизом «как бы чего не вышло». А вот Visibroker 3.4 вообще обходится без изменений и оставляет идентификаторы такими, как они есть.

Поскольку трансляция зависит от того, что за элемент языка IDL подвергается обработке, различается и количество файлов, получаемых в процессе генерации. Для пользовательских типов, например, будут созданы специальные файлы, имена которых заканчиваются суффиксами Helper и Holder.

Еще один интересный момент связан с зарезервированными именами. По спецификации, компилятор резервирует за собой следующие имена:

<тип>Helper, где <тип> — имя пользовательского
 типа;
<тип>Holder, где <тип> — имя пользовательского
 типа;
<базовыйТипJava>Holder, где <базовыйТипJava>
 — один из примитивных типов языка Java;
<интерфейс>Package, где <интерфейс> — имя
 интерфейса IDL.

Однако эксперименты по компиляции показали, что и idltojava и idl2java одинаково хорошо компилируют зарезервированные слова, избегая конфликтов. Тем не менее

написанные в спецификации правила следует соблюдать! Иначе вы рискуете попасть в сложную ситуацию при переходе с одного компилятора IDL на другой или в случае ужесточения правил в следующих версиях спецификации CORBA. Никто тогда не сможет поручиться за то, что компилятор не сгенерирует имена, совпадающие с вашими. Подобные ошибки могут быть трудно уловимыми!

Структурные элементы и вспомогательные классы

В отличие от двух предыдущих занятий, мы избрали иную последовательность рассмотрения элементов, потому что знание трансляции структурных элементов, а также назначения вспомогательных классов критичны для понимания остального материала.

Вспомогательные классы (Helper и Holder)

Если программист описывает собственные типы, в результате их трансляции появляются два вспомогательных класса, имена которых состоят из имени типа с добавлением суффиксов Helper и Holder. Они необходимы для корректной работы с объектами. Helper содержит «джентльменский» набор статических методов, упрощающих жизнь программисту, поскольку генерируемые методы выполняют одни и те же рутинные действия. Класс с суффиксом Holder работает «оболочкой» для пользовательского типа, когда его нужно передать в качестве параметров операции объекта. Да и генерация его происходит не во всех случаях — см. ниже «Описание типа (typedef)».

Класс-Helper всегда имеет статические методы для чтения и записи данных в поток read() и write(), упаковки данных в тип Any и распаковки (методы insert() и extract()), а также методы определения типа type() и его идентификатора в репозитарии id(). Прочие методы — от лукавого. Например, компилятор idl2java из Visibroker создает метод _orb(), который возвращает ссылку на инициализированный экземпляр ORB. После работы idltojava из Java 2 такой метод не возникает, зато появляется скрытый конструктор, не позволяющий создавать экземпляры объекта директивой new.

С классом-Holder дело обстоит несколько сложнее. Он должен не только уметь записывать данные в поток методом _write(), читать их оттуда методом _read() и возвращать код типа методом _typecode(). В нем должна быть предусмотрена открытая переменная value, хранящая значение, и два конструктора: один — по умолчанию, т.е. без параметров, и второй — с параметром, инициализирующим переменную value.

Модули

Модули служат для группировки типов, интерфейсов и прочих элементов, логически связанных друг с другом. Во время трансляции описания модулей превращаются в пакеты с теми же самыми именами, что и сами модули. Соответственно все описания типов внутри модулей после трансляции в классы и интерфейсы Java приобретают область видимости внутри сгенерированных пакетов. Если описания типов находятся за пределами модулей, то они транслируются в глобальный пакет Java, т. е. не включаются ни в один пакет.

Для примера опишем следующий модуль:

module UserModule
{
  typedef string UserType;
};

После его трансляции в выходном каталоге появится подкаталог с именем модуля, и в нем будут сохранены файлы, появившиеся в результате генерации исходных текстов для типа UserType. А в самих этих текстах появится строка принадлежности к пакету UserModule:

package UserModule;

Интерфейсы

Трансляция интерфейсов происходит намного сложнее, чем трансляция модулей. В первую очередь создаются описания общедоступных интерфейсов Java, наследуемые от базового CORBA-интерфейса org.omg.CORBA. Object. Однако Visibroker генерирует интерфейс, наследуемый от com.inprise.vbroker.CORBA.Object, который в свою очередь является наследником org.omg.CORBA. Object. Возьмем следующее описание на IDL:

interface UserInterface
{

};

После компиляции программой idltojava из Java 2 создается следующий интерфейс на языке Java:

public interface UserInterface 
		extends org.omg.CORBA.Object
{

}

Внутри сгенерированного интерфейса описываются операции, которые компилятор обнаружит в IDL-файле. Интересная трансформация происходит с атрибутами интерфейса. Для каждого из них создаются описания методов чтения и записи данных, хранимых атрибутом. Если атрибут объявлен как readonly, для него генерируется лишь метод чтения. Исходный текст на IDL:

attribute float UserAttribute;

будет транслирован в следующие описания методов:

float UserAttribute();
void UserAttribute(float arg);

Если IDL-интерфейс наследуется от другого интерфейса, то в его описании на Java также будет присутствовать наследование.

Теперь поговорим о параметрах операций. Любой параметр с модификатором in транслируется в аргумент метода, имеющий соответствующий тип на языке Java (см. разделы «Простые типы» и «Описание типа (typedef)»). То же самое и с возвращаемым операцией значением. А вот параметры inout и out — особый случай. Они не могут транслироваться непосредственно в параметры методов на таком языке высокого уровня, как Java. Поэтому приходится пользоваться Holder-классами. Программа-клиент подставляет в качестве параметра экземпляр подобного класса, в котором, как в контейнере, находится передаваемое значение. После передачи параметра по значению хранимые данные изменяются на серверной стороне и возвращаются клиенту, который «вскрывает контейнер» и извлекает новое значение аргумента. Например, показанная операция имеет параметр, объявленный как inout:

void userOperation(inout double param);

Компилятор IDL сделает из этого следующий метод на языке Java:

void userOperation(org.omg.CORBA.DoubleHolder
 param);

Как видите, вместо изначально задуманного типа параметра нужно подставлять экземпляр Holder-класса. Такой подход, конечно, создает дополнительные сложности программиста: придется создать экземпляр такого класса вручную. Но к этому быстро привыкаешь.

Для интерфейса также создаются класс-Helper и класс-Holder. Класс-Helper дополнительно к методам, описанным в разделе «Вспомогательные классы (Helper и Holder)», генерируется метод narrow(), с помощью которого делается приведение к оригинальному типу интерфейса. Дело в том, что программе при запросе ссылки на объект возвращается ссылка типа org.omg.CORBA.Object, которую необходимо привести к запрошенному типу перед использованием, что и делает narrow(). При невозможности произвести эту операцию происходит исключение CORBA::BAD_ PARAM.

Еще один метод генерируется idl2java из Visibroker. Он называется bind() и служит для получения ссылки на запрашиваемый объект. Поскольку bind() не является частью спецификации CORBA, многие компиляторы игнорируют его создание. И даже у idl2java имеется опция, отключающая создание bind().

Часто у программистов возникают сложности с пониманием того, как транслируются вложенные в описания интерфейсов конструкции. Кажется, что достаточно сгенерировать новый пакет с его именем и поместить в него внутреннее содержимое интерфейса. Однако, по спецификации CORBA, во избежание конфликтов имен нельзя создавать пакеты, имена которых совпадают с уже имеющимися именами. Поэтому решено задавать имена пакетов, добавляя к имени интерфейсов суффикс Package.

Опишем интерфейс, внутри которого объявляется пользовательский тип:

interface UserInterface
{
  typedef any UserType;
};

В результате трансляции получится пакет UserInterfacePackage, в который и будут помещены все сгенерированные для пользовательского типа файлы, и все они будут начинаться с директивы:

package UserInterfacePackage;

Простые типы

Трансляция простых типов IDL приводит к появлению соответствующих идентификаторов, но уже имеющих Java-типы. В табл. 1 показано соответствие между ними: если данный тип может привести к возникновению исключительной ситуации, то она отмечена в графе «Исключения».

Пока не все из приведенных в табл. 1 IDL-типов поддаются трансляции, поэтому они показаны курсивом. К примеру, как мы уже знаем из предыдущих занятий, тип fixed только заявлен в спецификации, но реализован будет позже. Частично это касается и типа long double, который объявлен в спецификации как нереализованный. Если попробовать компилятор idltojava из Java 2, то вы получите сообщения об ошибке. А вот idl2java из Visibroker 3.4 транслирует его в Java-тип double на свой страх и риск, поскольку в спецификации CORBA 2.2 ничего не сказано про предполагаемый тип, который должен появиться в результате трансляции. Возможно, трансляция long double будет производиться в такой класс Java, как java.math.BigFloat.

16.09.1999г.
Также в разделе

16/09/1999   №09

Эта рубрика в архиве
Список номеров за 

01 02 03 04 05 06
07 08 09 10 11 12
МаркетГид:



Об издательствеКак нас найти  •  Контакты
    Издания:     Computerworld     Windows IT Pro     LAN     Сети     Мир ПК     Открытые системы     Директор ИС    
    WhatCar?     ФСП     Publish     Классный журнал     Stuff     Oil&Gas     Лечащий врач     What Hi-Fi?    
Copyright © 1992-2010. All rights reserved.
TopList    Rambler's Top100 Service Rambler's Top100