Статьи

Начало работы с генерацией кода с помощью Xpand

Вы слышали о разработке программного обеспечения, основанной на моделях (MDD / MDSD), и думаете, «что это за модель с модом»? «Почему модели должны помогать мне быть более продуктивным», может быть, у вас есть еще одна мысль.

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

Краткий обзор

Xpand — это шаблонизатор, похожий на FreeMarker, Velocity, JET и JSP. Тем не менее, он имеет несколько уникальных свойств, которые делают использование Xpand очень подходящим для генерации кода из моделей, таких как безопасность типов и полиморфная диспетчеризация . Если вы не слышали этих терминов раньше, не бойтесь! Я покажу вам, как использовать Xpand на простом для понимания примере.

Обычный процесс написания генератора кода с помощью Xpand выглядит следующим образом:

  1. Определите структуру модели, которую вы хотите обработать. Это называется метамоделью
  2. Определите один или несколько шаблонов, которые научат генератор кода преобразовывать вашу модель в код.

Легко, не правда ли?

Использовать генератор кода еще проще:

  1. Создать модель
  2. Запустить генератор кода

Стоит отметить, что вы можете использовать Xpand для генерации кода практически для любого известного языка программирования. Все, что вы можете выразить в тексте, может быть сгенерировано с помощью Xpand. Поэтому, пока мы будем генерировать код HTML и Java в следующем примере, вы можете легко написать шаблоны кода, которые генерируют код для C #, Basic, Lua, SmallTalk, ABAP или любого другого языка программирования. Вы также можете создавать руководства и другие артефакты документации из ваших моделей, используя Xpand. Я успешно использовал Xpand для создания файлов DocBook из моделей. Эти файлы DocBook были затем преобразованы в файлы PDF и файлы интерактивной справки.

Подготовка вашей IDE

  1. Возьмите и установите последнюю версию Eclipse. На момент написания статьи я использовал Eclipse 3.6 M6 .
  2. Установите последнюю версию Xpand ( Справка -> Установить новое программное обеспечение … )
  3. Добавьте сайт обновлений Xpand (на момент написания этой статьи я использовал ночные сборки Xpand 1.0 с http://download.eclipse.org/modeling/m2t/xpand/updates/nightly/ )
  4. Добавить сайт обновления MWE ( http://download.eclipse.org/modeling/emft/mwe/updates/nightly/ )
  5. Выберите MWE и Xpand:

    Установите MWE и Xpand
  6. После обязательного перезапуска сделайте себе одолжение и установите кодировку платформы в UTF-8 !

Создание проекта генератора

Генераторы кода Xpand размещаются в плагинах Eclipse, главным образом потому, что это значительно упрощает обработку classpath. Сообщается, что люди использовали Maven для запуска генераторов кода Xpand, но сегодня мы не пойдем по этому пути. Давайте создадим простой генератор проекта:

  1. Откройте мастер нового проекта и выберите Xpand Project из списка
  2. Выберите осмысленное имя для вашего проекта (например, org.xpand.example.gettingstarted
  3. Выберите Создать образец Xpand-проекта на основе EMF.

После нажатия кнопки « Готово» мастер создаст для вас пример проекта генератора:

Макет проекта Xpand

Прежде чем мы сможем начать работу с этим проектом, нам нужно выполнить некоторые действия по очистке:

  1. Откройте src / metamodel / Checks.chk и удалите все его содержимое
  2. Откройте src / metamodel / Extensions.chk и удалите все его содержимое
  3. Откройте src / template / GeneratorExtensions.ext и удалите все его содержимое
  4. Удалить src / Model.xmi
  5. Не забудьте сохранить все измененные файлы

Создание Метамодели

Как упоминалось ранее, нам нужно определить структуру наших моделей, прежде чем мы действительно сможем начать писать шаблон кода.
Xpand способен понимать различные типы метамоделей. Например, если у вас есть файл схемы XML, вы можете использовать его как метамодель и тем самым разрешить Xpand использовать файлы XML, которые соответствуют вашей схеме, в качестве моделей ввода. Или, если у вас уже есть куча файлов Java, составляющих вашу модель данных, вы можете использовать их для генерации кода Xpand. Однако в этом уроке мы будем использовать метамодель Ecore для определения структуры наших моделей. Проект уже настроен для поддержки метамоделей Ecore, поэтому все, что нам нужно сделать, это открыть metamodel.ecore и определить структуру:

  1. Пожалуйста, откройте src / metamodel / metamodel.ecore
  2. ,

  3. Удалите следующие элементы из метамодели: Feature , Entity , Тип данных , тип , модель . Метамодель теперь должна быть пустой:

    Пустая метамодель
  4. Выберите метамодель пакета (как показано на скриншоте выше) и добавьте новый EClass ( контекстное меню -> New Child -> EClass ). Используйте представление свойств, чтобы изменить имя вновь созданного EClass на Model .
  5. Создать новую форму EClass
  6. Выберите вновь созданную форму EClass и добавьте следующие атрибуты EA :

    • имя , установите EType в EString
    • описание , EType = EString
    • title , EType = EString
  7. Выберите форму EClass и добавьте новую EReference , установив ее атрибуты следующим образом:

    • имя = формы
    • EType = Форма
    • Сдерживание = правда
    • Верхний предел = -1 (значение: не ограничено)
  8. Создайте новое поле EClass и добавьте в него следующие атрибуты EA:

    • имя , EType = EString
    • Lable , EType = Estring
  9. Создайте еще один EClass TextField , установив его свойства следующим образом:

    • name = TextField
    • ESuper Types = Поле
  10. Добавьте один EAttribute текст для текстового поля :

    • имя = текст , EType = EString
  11. Добавьте EClass MultiLineTextField в метамодель:

    • name = MultiLineTextTield
    • ESuper Types = TextField
  12. Теперь, когда у нас есть все, что нужно, нам, наконец, нужно добавить ссылку из формы в поле, чтобы мы могли позже добавить поля в форму. Выберите форму EClass и добавьте EReference к ней, установив ее свойства следующим образом:

    • имя = поля
    • EType = Поле
    • Сдерживание = правда
    • Верхний предел = -1 (значение: не ограничено)

Создание модели

Давайте теперь создадим модель, которая следует структуре метамодели:

  1. В metamodel.ecore выберите модель EClass
  2. Создайте экземпляр модели, выбрав « Создать динамический экземпляр …» в контекстном меню.
  3. Сохраните файл модели в src / Model.xmi

Теперь откроется редактор файла модели, и вы можете использовать редактор дерева для ввода следующей модели:

  • Добавьте форму к модели, видя следующие свойства:

    • Название: контекст
    • Описание: Отправить отзыв
    • Название: Контактная форма
  • Добавьте TextField в форму , задав следующие свойства:

    • Имя: имя
    • Метка: Имя
  • Добавьте еще один TextField в форму , задав следующие свойства:

    • Имя: электронная почта
    • Ярлык: электронная почта
  • Добавьте MultiLineTextField в форму , задав следующие свойства:

    • Имя: сообщение
    • Метка: сообщение

Ваша модель должна теперь выглядеть так:

Модель контакта

Создание генератора кода

Как упоминалось ранее, мы создадим генератор кода для простых форм. Ничего особенного, но достаточно, чтобы дать вам представление о том, как создавать шаблоны генератора.

Результат будет выглядеть так:

Форма обратной связи

Откройте src / template / Template.xpt и замените его содержимое следующим текстом:

«IMPORT metamodel»
«DEFINE main FOR Model»
«EXPAND form FOREACH forms»
«ENDDEFINE»

В первой строке мы импортируем метамодель, чтобы генератор (и редактор тоже) знали о структуре нашей модели. В строке 2 — 4 мы определяем шаблон кода с именем main , следя за тем, чтобы он был связан с элементами модели типа Model . Шаблон не делает ничего, кроме как вызвать другой шаблон (который мы определим через минуту) с именованной формой с коллекцией форм s, содержащихся в ссылочных формах текущей формы.

Добавьте следующие строки в файл шаблона, определяя шаблон для файла HTML:

«DEFINE form FOR Form»
«FILE name + ".html"»
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>«this.title»</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <link rel="stylesheet" type="text/css" href="../static/style.css" />
</head>

В первой строке мы запускаем шаблон, указывая его имя ( форму ) и тип, с которым он связан ( Форма ). На следующей строке мы используем оператор FILE, чтобы указать файл, в который будет записан вывод. Имя файла определяется путем конкатенации атрибута имя текущей формы и строковый литерал «.html» .

Продолжите шаблон, добавив следующий текст:

<body>
  <div id="page-wrap">
    <h1>«this.title»</h1><br /><br />
    <p>«this.description»</p>
    <div id="form-area">

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

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

      <form method="post" action="form.php">
        «EXPAND field FOREACH this.fields»
        <input type="submit" name="submit" value="Submit" class="submit-button" />
      </form>
      <div style="clear: both;"></div>
    </div>
  </div>
</body>
</html>
«ENDFILE»
«ENDDEFINE»

Оператор EXPAND вызовет еще один подшаблон с полем имени . Этот суб-шаблон будет вызываться для каждого элемента в атрибуте fields (ссылка) текущей формы .

Возможно, вы помните, что мы определили три различных типа > полей s в метамодели:

  1. Поле (которое является суперклассом для двух других типов полей
  2. Текстовое поле
  3. MultiLineTextField

Как следует из их имен, TextField будет однострочным полем ввода текста, тогда как MultiLineTextField будет многострочным полем ввода текста. Нам нужно каким-то образом иметь возможность визуализировать различный код HTMNL для каждого из этих различных типов текстовых полей.

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

Добавьте следующий код в файл шаблона:

«DEFINE field FOR Field»
«ERROR "should not happen"»
«ENDDEFINE»
«DEFINE field FOR TextField»
        <label for="«this.name»">«this.label»:</label>
        <input type="text" name="«this.name»" id="«this.name»" />
«ENDDEFINE»
«DEFINE field FOR MultiLineTextField»
        <label for="«this.name»">«this.label»:</label>
        <textarea name="«this.name»" id="«this.name»" rows="20" cols="20"></textarea>
«ENDDEFINE»

Как видите, все три шаблона имеют одинаковое имя. Отличается только тип, к которому они привязаны. Этого достаточно, чтобы Xpand знал, какой шаблон выбрать в соответствии с типом текущего элемента модели. Давайте предположим, что Xpand выполняет итерацию модели, а текущим элементом модели является TextField . Хотя Field является прямым супертипом TextField , Xpand будет вызывать не первый шаблон ( «DEFINE field FOR Field» ), а второй шаблон ( «DEFINE field FOR TextField» ), так как это наиболее конкретное соответствие для типа модельный элемент.

Запуск генератора кода

Если вы выполнили вышеуказанные шаги, запуск генератора кода — это очень просто:

Откройте контекстное меню в src / workflow / workflow.mwe и выберите Run As -> MWE Workflow

Это запустит генератор кода. Вы увидите некоторые сообщения журнала в представлении консоли. Если все прошло хорошо, вывод в консоли будет выглядеть примерно так:

...
1503 INFO  Generator          - Written 1 files to outlet [default](src-gen)
1503 INFO  WorkflowRunner     - workflow completed in 650ms!

Результат генерации кода можно найти в src-gen / contact.html . Поскольку этот файл имеет некоторые зависимости от CSS / файлов изображений, пожалуйста, загрузите файлы из статической папки ( здесь ) и поместите их в свой проект, прежде чем открывать contact.html в своем браузере.

Куда пойти отсюда

Если вы хотите узнать больше об Xpand, обязательно посетите мой доклад. Используйте модели и позвольте компьютеру выполнить основную работу с Xpand на EclipseCon 2010. В этом выступлении я покажу некоторые более сложные темы (такие как картриджи генератора, использование Xtend). чтобы расширить ваши модели, разделив шаблоны кода, используя другие метамодели для определения ваших моделей).

Xpand поставляется с обширной документацией (просто зайдите в Справка -> Содержание справки -> Документация Xpand в Eclipse). Вы также можете получить помощь по Xpand на форумах сообщества Eclipse.

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

Без сомнения, вы слышали о Xtext . Xpand и Xtext отлично сочетаются друг с другом: вы можете использовать Xtext для определения структуры ваших моделей и создавать великолепные текстовые редакторы для редактирования ваших моделей. Затем с помощью Xpand создайте генераторы кода, которые берут ваши текстовые модели и превращают их в работающее программное обеспечение. На самом деле, Xtext поставляется с мастером, который поможет вам создать проект генератора кода для вашего DSL.

Загрузки

Код для этого руководства можно найти в моем репозитории SVN в Google Code .

С http://www.peterfriese.de