Kylix 2: Что новенького?

Андрей Боровский - kylixportal@narod.ru

If you're like most developers, you don't understand Kylix in every detail, nor do you feel a need to do so.
Справочная система Borland Kylix 2

Недавно компания Borland вновь порадовала всех, пристрастившихся к "винной чаше" (напомню, что именно так переводится слово kylix), выпустив новую версию среды разработки на основе ObjectPascal. В этой статье мы рассмотрим новые возможности Kylix 2, а также попытаемся оценить достоинства, недостатки и перспективы развития этого продукта.

Как и предыдущая версия, Kylix 2 поставляется в 3-х вариантах, но называются они теперь по-другому: Enterprise, Professional и Open. Самый “тяжеловесный” вариант, Enterprise Edition, насчитывает более 190 компонентов библиотеки CLX и включает мощные средства взаимодействия с базами данных и создания распределенных приложений. В варианте Professional Edition насчитывается около 165 компонентов CLX, а средства для работы с базами данных несколько урезаны по сравнению с Enterprise Edition. Самый “легкий” вариант, распространяемый бесплатно Open Edition, включает около 70 компонентов CLX. При этом в Open Edition отсутствуют средства для работы с базами данных и разработки приложений для Web-серверов. Кроме того бесплатный вариант Kylix 2 лишен таких "приятных мелочей" как исходные тексты модулей библиотеки CLX, а также некоторых функций редактора кода, например всплывающих подсказок для символов в окне редактора (ToolTip Symbol Insight) и механизма завершения кода (Code Completion Wizard). Далее в этой статье все новые возможности и характеристики Kylix 2 будут рассматриваться на примере наиболее полного варианта Enterprise Edition.

Среди главных новшеств Kylix 2 следует отметить средства разработки приложений Web-служб (Web Services), основанных на протоколе SOAP, поддержку сценариев на стороне сервера (server-side scripting) и средства преобразования данных в формате XML в наборы данных Dataset.

На первый взгляд

Отличия новой версии Kylix от предшествующей заметны уже в меню запуска программ. В меню Borland Kylix 2 теперь три пункта: запуск самой среды Kylix IDE, справочной системы Kylix и утилиты XML Mapper. Итак, запускаем интегрированную среду разработки. Изменения по сравнению с предыдущей версией не сразу бросаются в глаза, но они есть и их немало. Прежде всего замечаем, что палитра компонентов обогатилась двумя новыми вкладками: WebSnap и WebServices. Группа WebSnap включает компоненты для быстрой разработки мощных приложений для Web-серверов с поддержкой сценариев на стороне сервера, аутентификации и авторизации пользователей, интеграции с базами данных. Назвав эти компоненты "WebSnap", Borland очевидно намекает на то, что теперь Web-приложения можно создавать "одним щелчком мыши" и как мы убедимся, это утверждение не так уж далеко от действительности.

Компоненты WebServices предназначены для разработки серверов и клиентов Web-служб, основанных на протоколе SOAP. Так как протокол SOAP, как впрочем и другие современные Web-технологии, опирается на язык разметки XML, вполне естественно, что в библиотеку CLX были введены компоненты для работы с данными в формате XML. На вкладке DataAccess появились три новых компонента: XMLTransform, XMLTransformProvider и XMLTransformClient, предназначенные для преобразования между данными в формате XML и традиционными наборами данных Delphi/Kylix, а на вкладке Internet - компонент XMLDocument, облегчающий синтаксический анализ (parsing) XML документов. Среди новых компонентов Kylix 2 следует отметить также компонент TAnimate, позволяющий воспроизводить анимацию на основе серии изображений.

Не остался без изменений и диалог New группы меню File. В списке команд на вкладке New появился новый элемент XML Data Binding, который запускает мастер (wizard), позволяющий создать группу объектов для работы с заданным XML документом. Появились также три новые вкладки: WebSnap и WebServices, предназначенные для создания заготовок приложений WebSnap и приложений Web-служб соответственно и вкладка CORBA, содержащая команды для создания заготовок клиентов и серверов одноименной технологии. Далее мы подробно остановимся на компонентах WebServices и WebSnap, которые Borland справедливо считает главными новшествами своего продукта.

Разработка приложений Web-служб

По данным компании Evans Data, (на которые Borland ссылается в своем пресс-релизе от 6 ноября), 70% Linux-разаботчиков считают, что Web-службы "представляют собой будущее интернет-приложений". Неудивительно по этому, что в новой версии Kylix разработке приложений Web-служб уделено особое внимание. Kylix 2 позволяет создавать приложения Web-служб на основе протокола SOAP.

Протокол SOAP (Simple Object Access Protocol - простой протокол доступа к объектам) предназначен для организации взаимодействия между распределенными приложениями на основе таких распространенных протоколов как HTTP и XML. В рамках протокола SOAP приложение-сервер предоставляет приложению-клиенту доступ к методам ряда своих объектов. Клиент посылает серверу запрос, содержащий команды на выполнение соответствующих методов и получает в ответ данные о результатах. SOAP позволяет организовать взаимодействие между компонентами распределенной системы, написанными на разных языках программирования и выполняющимися на разных платформах. Для описания экспортируемых интерфейсов SOAP используется спецификация WSDL. Подробное рассмотрение протокола SOAP выходит за рамки этой статьи, отмечу только, что как и в случае с классическим CGI, приложения-серверы SOAP могут быть написаны на чистом ObjectPascal без использования специальных объектов, но как и в случае с CGI, использование специальных компонентов существенно упрощает процесс разработки.

Разработка SOAP-приложений в Kylix 2 очень похожа на процесс создания обычного Kylix-приложения. Для того, чтобы создать приложение-сервер, выбираем пункт SOAP Server Application на вкладке WebServices диалогового окна New Items. Как и другие приложения для Web-сервера, сервер SOAP можно разрабатывать в одном из двух вариантов: в виде независимого CGI-приложения и в виде разделяемого модуля для сервера Apache. После выбора варианта сервера Kylix автоматически создает его главный модуль - форму, содержащую три основных компонента - HTTPSoapDispatcher, HTTPSoapPascalInvoker и WSDLHTMLPublish. HTTPSoapDispatcher выполняет маршрутизацию вызовов SOAP, HTTPSoapPascalInvoker отвечает за вызов соответствующих методов объектов Kylix, а WSDLHTMLPublish динамически генерирует описание интерфейса в формате WSDL в ответ на запрос клиента.

Мы создали костяк приложения-сервера SOAP, но наш сервер не экспортирует никаких интерфейсов. Справочная система Kylix настоятельно рекомендует размещать объекты и их интерфейсы в собственных модулях, что мы и сделаем. Выбираем пункт SOAP Server Data Module на той же вкладке WebServices диалога New Items и в открывшемся окне вводим имя нового класса. В нашем проекте появляется новый модуль, в котором Kylix почти все уже сделал за нас: создал описание объекта и соответствующего интерфейса, сгенерировал для него уникальный идентификатор, объявил и вызвал функции для регистрации интерфейса и объекта во внутренней базе данных приложения. Нам осталось только добавить в описание класса и интерфейса методы, реализующие функциональность сервера. В принципе с формой Web-модуля можно работать также, как и с формой обычного приложения, т. е. добавлять компоненты, назначать обработчики свойств и т. п. Ниже приводится исходный код модуля с автоматически сгенерированным классом TMyClass и добавленными к нему методами.

unit MyClass;

interface

uses
SysUtils, Classes, InvokeRegistry, Midas, SOAPMidas, SOAPDm,
HTTPApp, HTTPProd, StdConvs;

type

IMyClass = interface(IAppServer)
['{0A0EEBA1-C6D5-D511-8973-20465108E021}']
function Cel2Fahr(Value : Double) : Double; stdcall;
function Fahr2Cel(Value : Double) : Double; stdcall;
end;

TMyClass = class(TSoapDataModule, IMyClass, IAppServer)

private

public
function Cel2Fahr(Value : Double) : Double; stdcall;
function Fahr2Cel(Value : Double) : Double; stdcall;
end;

implementation

{$R *.xfm}

procedure TMyClassCreateInstance(out obj: TObject);
begin
obj := TMyClass.Create(nil);
end;

function TMyClass.Cel2Fahr;
begin
Result := CelsiusToFahrenheit(Value);
end;

function TMyClass.Fahr2Cel;
begin
Result := FahrenheitToCelsius(Value);
end;

initialization
InvRegistry.RegisterInvokableClass(TMyClass,
TMyClassCreateInstance);
InvRegistry.RegisterInterface(TypeInfo(IMyClass));
end.

Как видно из этого листинга, наш сервер выполняет невероятно важную функцию: переводит значения температуры по шкале Цельсия в шкалу Фаренгейта и наоборот. Кстати, перевод значений из одной шкалы в другую выполняется при помощи функций из появившегося в Kylix 2 модуля StdConvs.

Процесс создания SOAP-сервера завершен. Осталось только скомпилировать проект и скопировать полученный модуль в соответствующий каталог Web-сервера Apache. Размеры скомпилированного модуля впечатляют: мегабайт с лишним. Однако, взглянем на это с другой стороны. Только что мы, буквально за пять минут, создали настоящий SOAP-сервер, наделенный такими возможностями, как динамическая генерация WSDL-описаний.

Написать SOAP-клиент еще проще, чем написать сервер. Для написания клиента нам потребуется всего лишь один специальный компонент - HTTPRIO (он расположен на вкладке WebServices). Создадим новое стандартное приложение Kylix и поместим компонент HTTPRIO в его форму. Назначим свойству URL компонента HTTPRIO строку, соответствующую URL нашего SOAP-сервера (например 'http://localhost/cgi-bin/SOAPServ/SOAP/', где SOAPServ – имя нашего модуля). Теперь нам потребуется описание интерфейса, экспортируемого сервером. Компонент HTTPRIO может получить такое описание из публикуемой сервером WSDL-страницы, однако у нас есть модуль MyClass, в котором нужный интерфейс уже описан. Добавим модуль MyClass в раздел uses главного модуля нашего приложения, добавим переменную MyIntf типа IMyClass и в конструкторе формы напишем:

MyIntf := HTTPRIO1 as IMyClass;

Теперь мы можем в приложении-клиенте обращаться к методам IMyClass Cel2Fahr и Fahr2Cel. Запрос на выполнение методов будет передан серверу SOAP. В деструкторе формы следует присвоить переменной MyIntf значение nil, чтобы приложение не пыталось дважды удалить один и тот же объект.

При проверке работы клиента вам может показаться, что клиент использует реализации методов Cel2Fahr и Fahr2Cel из "своего" модуля MyClass, но это не так. Чтобы убедиться в этом, попробуйте запустить клиент, отключив предварительно сервер Apache.

Форма главного модуля SOAP-сервера

В заключение этого раздела рассмотрим еще одну интересную возможность построения интерфейсов. Если сервер SOAP написан на другом языке программирования или у вас нет доступа к модулям, в которых определены экспортируемые интерфейсы, SOAP-клиент должен будет воссоздавать интерфейс на основе данных WSDL. Как было сказано выше, компонент HTTPRIO способен построить интерфейс при помощи WSDL во время выполнения программы. Однако, описание удаленного интерфейса может понадобиться вам еще на стадии разработки и Kylix 2 предоставляет возможность получить его.

Вернемся к нашему примеру. В адресной строке броузера наберите http://localhost/cgi-bin/SOAPServ/wsdl. На открывшейся странице щелкните ссылку WSDL for IMyClass. Броузер откроет новую страницу. Хотя в окне броузера ничего нет, вы только что загрузили описание интерфейса IMyClass на языке WSDL. Сохраните эту "пустую" страницу на диске, присвоив файлу расширение wsdl. Теперь создайте новый проект в Borland Kylix, и на вкладке WebServices диалога New Items выберите элемент Web Services Importer. В открывшемся диалоговом окне укажите имя сохраненного wsdl файла. После этого в ваш проект будет добавлен новый модуль, содержащий объявление интерфейса IMyClass, полученное из документа wsdl.

Компоненты WebSnap

Набор компонентов WebSnap настолько многообразен, а возможности этих компонентов столь многочисленны, что для полного их описания не хватило бы и отдельной статьи. В этом разделе мы лишь кратко остановимся на таких возможностях WebSnap как поддержка сценариев на стороне сервера (server-side scripting) и контроль удаленных пользователей, работающих с приложением.

Для того, чтобы понять смысл сценариев (скриптов), выполняемых на стороне сервера, следует вспомнить "идеологию" компонентов-генераторов контента (content-producers). Одна из задач компонентов-генераторов заключается в том, чтобы вывести описание содержимого HTML страниц, предоставляемых сервером, за пределы самого приложения. Например, компонент TPageProducer использует HTML-шаблон, в котором во время выполнения программы заменяются лишь отдельные тэги. Шаблон может храниться в отдельном файле и изменяться уже после компиляции приложения, что, кроме прочего, позволяет пользователям вашей программы настраивать ее, не имея доступа к исходным текстам.

Поддержка сценариев на стороне сервера развивает эту тенденцию. В новой версии Kylix компонент TPageProducer "обзавелся" свойством ScriptEngine, так что теперь кроме специальных тэгов в его шаблоны можно включать и сценарии, написанные на языке JavaScript (в Kylix 2 для поддержки сценариев используется движок SpiderMonkey, являющийся частью открытого проекта Mozilla). В тексте шаблона блоки сценариев выделяются элементами <% и %>. В качестве примера приведем скрипт, выводящий первые 10 чисел Фибоначчи:

<%
fibp = 0;
fib = 1;
Response.Write("No 1 : 1<BR>");
for (i = 2; i <= 10; i++)
{
fib = fib + fibp;
fibp = fib - fibp;
Response.Write("No "+i+" : "+fib+"<BR>");
}
%>

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

No 1 : 1<BR>No 2 : 1<BR>No 3 : 2<BR>No 4 : 3<BR>No 5 : 5<BR>No 6 : 8<BR>No 7 : 13<BR>No 8 : 21<BR>No 9 : 34<BR>No 10 : 55<BR>

Таким образом технология сценариев на стороне сервера позволяет модифицировать при помощи шаблонов не только внешний вид динамически генерируемых страниц, но и саму функциональность сервера. В классическом CGI-приложении, созданном в Kylix, ответ на запрос клиента формируется обработчиком события OnAction. При этом обработчик OnAction получает доступ к ряду объектов сервера, в том числе к объектам Request и Response. Сценарии, выполняемые на стороне сервера, позволяют "переложить" функции обработчиков OnAction на шаблоны динамических страниц. Так же как и обработчики OnAction, скрипты на страницах шаблонов получают доступ к объектам приложения сервера. В приведенном выше примере мы обращались к методам объекта Response. В число объектов, к которым можно получить доступ со страниц шаблонов, входят также объекты Application, EndUser, Pages, Request, Session и другие.

Как и обработчики событий, сценарии на стороне сервера должны получать доступ не только к стандартным объектам приложения, но и к тем объектам, которые создает программист. Для этой цели в Kylix 2 реализованы компоненты-адаптеры. Адаптеры позволяют разработчику сервера добавлять в объектную модель скриптов собственные поля и методы, отражающие специфику сервера. Генерация шаблонов, содержащих скрипты, обращающиеся к полям и методам адаптеров, может быть автоматизирована при помощи компонента AdapterPageProducer. Нельзя не отметить также весьма удобную возможность редактирования шаблонов страниц и просмотра результатов непосредственно в окне редактора Kylix.

Просмотр HTML-страницы в окне редактора Kylix

Второй важной новинкой технологии WebSnap являются компоненты, осуществляющие аутентификацию и авторизацию удаленных пользователей и поддерживающие список пользователей, зарегистрированных на сервере. Стоит ли говорить, что без эти функции совершенно необходимы современным приложениям для сферы электронного бизнеса. Страницы, содержащие формы для регистрации создаются при помощи компонента LoginFormAdapter. Компонент WebUserList позволяет поддерживать список пользователей, а объект EndUser, и соответствующий адаптер доступные из скриптов на шаблонах страниц, позволяет следить за состоянием удаленного пользователя, обращающегося к серверу в данный момент (например, выяснить, зарегистрировался ли пользователь).

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

Не столь значительные новшества ...

Кроме описанных ранее стратегических новшеств, среда разработки приобрела множество менее существенных дополнений. Новые модули ConvUtils и StdConvs содержат функции, позволяют проводить преобразования значений между различными системами единиц, а модуль DateUtils предоставляет широкий спектр функций для работы с датой. Добавлен модуль StrUtils, содержащий функции для работы со строками, позволяющие выполнять такие операции как замена подстроки в строке, поиск префиксов и суффиксов и т. п. Ничего особенного, конечно, но раньше такие функции разработчикам приходилось писать самостоятельно, а теперь появился стандарт. Улучшения коснулись и библиотеки CLX. Многие элементы управления теперь поддерживают события OnMouseEnter и OnMouseLeave, а в компоненте "строка ввода" (TEdit) стали возможны операции undo и redo.

... и мелкие недостатки

Новая версия Kylix представляет собой существенный шаг вперед и как средство разработки от Borland и как среда программирования для Linux и потому говорить о ее недостатках не хочется. Но и молчать о них нельзя ;-). Так и не исправлена ошибка в интерфейсе CLXDisplay API, замеченная мной еще в первой версии: функция QEvent_IsQDropEvent, экспортируемая libqtintf, импортируется в модуле Qt под именем QEvent_IsQDropEventEvent. Вызов функции QEvent_IsQDropEventEvent приведет к тому, что программа завершится не успев начаться. Для того, чтобы преодолеть эту проблему, следует либо исправить и перекомпилировать модуль Qt, либо импортировать функцию явным образом:

function QEvent_isQDropEvent(e: QEventH): Boolean; cdecl;
...
function QEvent_isQDropEvent; external 'libqtintf.so' name 'QEvent_isQDropEvent'

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

С разделяемыми библиотеками, сопровождающими Kylix, связана и еще одна проблема. Вопрос, который чаще всего задают программисты, начинающие работать в Kylix, звучит так: "почему моя программа прекрасно запускается в Kylix, но не выполняется отдельно от среды разработки?" Причина кроется в несовместимости версии библиотеки libqt, поставляемой вместе с Kylix и одноименной библиотеки из Linux-дистрибутива. Kylix 2 использует библиотеку libqt.so.2.3.0, и если в вашей системе установлена другая версия, вы, скорее всего, столкнетесь с указанной ситуацией. Конечно, в этом "виноват" не столько Kylix, сколько сама Qt-library, более новые версии которой часто не имеют обратной совместимости с более старыми версиями. Вообще-то это не является серьезной проблемой для Linux, так как большинство приложений, использующих Qt, компилируются из исходников специально для каждого дистрибутива. Для Kylix же самое безопасное решение - распространять приложения с собственной версией библиотеки libqt и запускать программы из специального скрипта, который добавлял бы каталог с библиотеками libqt и libqtintf в переменную LD_LIBRARY_PATH.

Плохо проработан в Kylix вывод текста в различных кодировках. Внесите в форму Kylix компонент TextBrowser и откройте в нем HTML-страницу, созданную, например, в кодировке cp-1251. Если эта кодировка не установлена по умолчанию в вашей системе, окно броузера заполнят вопросительные знаки. Проблемы возникнут при выводе текста в любых кодировках кроме базовой латинской и той, которая установлена при локализации. И это при том, что Konqueror Browser, основанный на том же Qt-классе QTextBrowser, прекрасно справится с выводом страниц в русской кодировке Windows даже в нерусифицированных версиях Linux. Дело в том, что хотя Qt library обладает весьма широкими средствами для работы с разными кодировками и, в том числе, предоставляет целый ряд текстовых кодеков, к которым к тому же можно добавлять свои собственные, Kylix не позволяет нам воспользоваться всем этим богатством. Функции для работы с классом QTextCodec в модуле Qt не определены, да и получение низкоуровневневого контроля над выводом текста в компонентах не предусмотрено.

Не могу удержаться и не сказать несколько грустных слов по поводу вышедшего пару месяцев назад бесплатного Kylix Open Edition. Конечно, "дареному коню в зубы не смотрят", но все же "Большой стиль" требует совершенства и в малом. Все программы, скомпилированные в Kylix Open Edition при запуске выдают предостерегающее сообщение в том смысле, что "... эта программа скомпилирована в бесплатной версии Kylix и должна распространяться на условиях GPL". В программах, обладающих GUI, это напоминание выводится в специальном окне, а в консольных приложениях - в стандартный поток вывода. И если в случае с графическим интерфейсом навязчивое окошко вызывает лишь раздражение (ну почему нас всех заранее подозревают в воровстве?), то в консольных программах выдача "несанкционированных" программистом символов может стать технической проблемой. Речь идет о ситуации, когда приложение обменивается данными с другими процессами через стандартный поток ввода-вывода (как например в случае CGI-приложений).

Итак, пришла пора ответить на самый важный вопрос, который порой возникает у некоторых представителей Linux-сообщества:

А нужен ли нам Kylix?

Отвечу на этот вопрос “да”. Дело не только в том, что на сегодняшний день Kylix – пожалуй самая совершенная среда визуальной разработки для Linux, и даже не в том, что за время, прошедшее с момента выхода первой версии Delphi в 1995 году, сложился широкий круг программистов – приверженцев визуальной разработки на языке ObjectPascal. Главное, на мой взгляд, то, что благодаря таким средствам как Borland Kylix, Linux начинает уверенно говорить на языке бизнес-приложений и корпоративного программирования, что очень важно с точки зрения дальнейшего укрепления позиций этой операционной системы.


Статья была впервые напечатана в журнале "Программист" (№ 1, 2002). Любая перепечатка статьи возможна только с разрешения редакции журнала.
Используются технологии uCoz