Матрёшка: DHTML_translator

Компонент DHTML_translator решает задачу трансляции шаблонов динамических HTML страниц в исходные тексты подпрограмм‐генераторов страниц. По мотивам технологии Java Server Page. Он позволяет веб‐разработчикам легко создавать содержимое, которое имеет как статические, так и динамические компоненты.

В качестве формата входного файла был выбран XML‐шаблон. Его рассмотрим немного позднее.

Результатом работы DHTML транслятора является *.adb — файл сгенерированного исходного кода, который готов для включения в проект AWS‐приложения. Кроме этого файла проект AWS‐приложения должен содержать файлы:

  • *.ads — спецификацию созданного *.adb файла. Файл *.ads должен иметь содержание:

          

          
    with AWS.Response;
    with AWS.Status;

    package A is
       function Call_Back (Request : AWS.Status.Data)
                       return AWS.Response.Data;
    end A;

Здесь A — имя пакета вашей программы — оно же имя *.adb файла, полученного в результате работы транслятора.

  • main.adb — главный файл проекта (может иметь любое имя). Файл должен иметь содержание:

          

          
    with AWS.Default;
    with AWS.Server;
    with A;

    procedure main is
       WS : AWS.Server.HTTP;
    begin
       AWS.Server.Start (WS, "Hello World", 1, A.Call_Back'Access);
       delay 100.0;
       AWS.Server.Shutdown (WS);
    end main;
  • project_name.gpr — непосредственно проектный файл, в котором должны быть подключены проектные файлы matreshka_league.gpr и matreshka_xml.gpr. Содержание проектного файла:

          

          
    with "aws";
    with "matreshka_league.gpr";
    with "matreshka_xml.gpr";

    project Project_Name is
       for Source_Dirs use (".");
       for Main use ("main.adb");
       package Builder is
          for Default_Switches ("Ada") use ("-gnat05");
       end Builder;
    end Project_Name

Формат входного XML файла

Покажем формат шаблона на примере:

<?xml version="1.0" encoding="UTF-8"?>
<asp:root xmlns:asp="http://www.ada-ru.org/ASP">
  <asp:with package="League.Calendars.ISO_8601"/>
  <asp:body>
    <html xmlns="http://www.w3.org/1999/xhtml">
      <p>Current Time
        <asp:expression>
          Writer.Characters (League.Calendars.ISO_8601.Image(League.Calendars.Clock));
        </asp:expression>
      </p>
    </html>
  </asp:body>
</asp:root>

Где:

  • root — корневой элемент, пространство имен asp — пространство имен тегов/атрибутов, которые нужно воспринимать как часть программы
  • with — элемент, содержащий атрибут package, с помощью которого можно подключать необходимые пакеты
  • body — элемент, свидетельствующий о начале тела программы генератора XML страницы
  • expression — элемент, внутри которого текст воспринимается как код программы, а не разметка. Метод Characters объекта Writer служит для добавления текста в конечный HTML файл.

Обязательными являются: объявление xml, а также элементы: root и body.

Такой шаблон предназначен для построения страниц вида:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<p>Current Time
2011-07-20 13:34:00
</p>
</html>

Анализ результата работы транслятора

Транслятор переведет шаблон в код так:


          

          
with XML.SAX.Attributes;
with XML.SAX.Pretty_Writers;
with League.Text_Codecs;
with League.Strings;
with League.Calendars.ISO_8601;

package body A is
   function "+" (Item : Wide_Wide_String)
         return League.Strings.Universal_String
      renames League.Strings.To_Universal_String;
   function Call_Back (Request : AWS.Status.Data)
         return AWS.Response.Data is
      pragma Unreferenced (Request);
      Encoder : League.Text_Codecs.Text_Codec
              := League.Text_Codecs.Codec (+"utf-8");
      Writer : XML.SAX.Pretty_Writers.SAX_Pretty_Writer;
      Attributes : XML.SAX.Attributes.SAX_Attributes;
   begin
      Writer.Start_Document;
      Writer.Start_Prefix_Mapping(+"",
                                  +"http://www.w3.org/1999/xhtml");
      Attributes.Clear;
      Writer.Start_Element (+"http://www.w3.org/1999/xhtml",
                            +"html",
                            +"html",
                            Attributes);
      Attributes.Clear;
      Writer.Start_Element (+"http://www.w3.org/1999/xhtml",
                            +"p",
                            +"p",
                            Attributes);
      Writer.Characters (+"Current Time ");
      Writer.Characters (League.Calendars.ISO_8601.Image
                                   (League.Calendars.Clock));
      Writer.End_Element (+"http://www.w3.org/1999/xhtml",
                          +"p",
                          +"p");
      Writer.End_Element (+"http://www.w3.org/1999/xhtml",
                          +"html",
                          "html");
      Writer.End_Prefix_Mapping(+"");
      Writer.End_Document;
      return AWS.Response.Build
                          ("application/xhtml+xml",
                Encoder.Encode (Writer.Text).To_Stream_Element_Array);
   end Call_Back;
end A;

Пакеты XML.SAX.Pretty_Writers и XML.SAX.Attributes необходимы для генерации XML кода. Пакет League.Text_Codecs необходим для работы с текстовыми кодеками. Пакет League.Strings необходим для работы с Universal_String. Пакет League.Calendars.ISO_8601 необходим для поддержки date/time операций. Далее после подключения всех необходимых пакетов генерируется стандартное определение пакета. Это определение содержит две функции: дополнительная функция, переопределяющая унарный плюс для удобства конвертации данных из типа Wide_Wide_String в тип Universal_String и функцию Call_Back, которая будет генерировать ответ на пользовательский запрос. В ней для подавления предупреждений о том, что Request не используется в текущем модуле, генерируется директива pragma Unreferenced. Создаются объекты: Encoder (необходим для преобразования кодировки xml файла в UTF-8), Writer и Attributes (необходимы для генерации XML‐кода).

Далее генерируется тело Call_Back. Метод Start_Document определяет начало xml документа. Далее определяется пространство имен по умолчанию. Создается открывающийся тег <html> без атрибутов (пространство имен — по умолчанию). Далее создается открывающийся тег <p> без атрибутов (пространство имен — по умолчанию). Генерируется текст внутри тега <p>. Далее аналогично в обратном порядке. Метод End_Document определяет конец xml документа соответственно. В самом конце генерируется и возвращается ответ.


Автор: Дмитрий Штефан
Дата: 01.09.2011