Актуально: ИТ-решение

Оборудование за 1 рубль

Позволяет корпоративным клиентам до 31 августа этого года приобрести оборудование для подключения к Интернету по мобильной сети оператора всего за 1 рубль.
Читайте подробности>>
 




Мир ПК :: Мир ПК

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

в buzz в мой мир в twitter версия для печатисохранить в pdf

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

Очередное занятие мы посвятим трансляции 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г


Комментарии:


Для того, чтобы оставить комментарий авторизуйтесь или зарегистрируйтесь.

Новости ОСП-ТВ - 03.09.10


В номере

17/03/2000 №03


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



Инфозоны

DIRECTUM EVERYWHERE

УРАЛХИМ признал DIRECTUM

Система DIRECTUM стала корпоративным стандартом электронного документооборота в масштабах всего холдинга "Уралхим".

Уфа внедряет электронный муниципалитет

Платформа DIRECTUM стала центральным звеном в создаваемой информационной системе, направленной на повышение эффективности и открытости местных органов власти.

Цена вопроса

Кто и когда должен оценивать эффективность ECM-проектов? Как перейти от общих результатов к конкретным количественным характеристикам?

DIRECTUM во власти

Внедрение СЭД в Правительстве Астраханской области: система управления делами для 12 министерств и более 1300 сотрудников.

OSP.RU :: Написать письмо.