Как легко можно заметить, исходники на JSP могут быть отформатированы двумя равно законными способами:

<!-- некая разметка ->     <%    /*   некий Java код   */%> <!-- некая разметка ->
ИЛИ
/*   некий Java код   */     %>   <!-- некая разметка -> <% /*   некий Java код   */

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

Первое преимущество языка HybridJava над JSP в бросающемся в глаза отсутствии мусорного синтаксиса: <% и %> разделителей, которые обычно делают JSP страницы еле читаемыми.

Другое преимущество заключается в более строгом контроле синтаксиса. Наличие объединенной формальной грамматики делает возможным раннее обнаружение синтаксических ошибок. И не только синтаксических проблем в Java и HTML частях отдельно, но и синтаксических проблем их пересечения, как например в таком случае: {<b>}</b>. Хотя текущая имплементация компилятора HybridJava все еще не полностью использует эту возможность, она тем не менее контролирует многие случаи ошибочного синтаксиса при примерно 60-ти разных сообщениях об ошибках.

HybridJava имеет гибкую, простую и последовательную концепцию виджета, которая сама по себе не предполагает никакого дополнительного программирования на Java. В отличие от известных имплементаций пользовательских тагов, виджеты HybridJava могут иметь несколько именованых точек вставки (используя терминологию JSP 2.0 - несколько тел). Это создает целое дополнительное измерение для дизайнера компонент.

Другое уникальное свойство, это прозрачность HTML кода и виджетов для контекста Java. Пара тагов <p></p> или <widget1></widget1> настолько же прозрачена для Java контекста как и пара фигурных скобок в Java { }. HTML и таги виджетов даже создают Java блоки.

Синтаксис

Язык HybridJava определен через слияние HTML с подмножеством Java на уровне грамматик. Код на HybridJava содержит как Java код, так и HTML. Таги, принадлежащие HTML представляют HTML элементы. Для элементов, которые могут иметь закрывающий таг, оный должен присутствовать. HTML элементы не имеющие закрывающего тага могут как иметь косую черту так и не иметь её. Например, <br/> и <br>означают одно и то же. Таким образом, HybridJava являетя дружественным по отношению к XHTML. Другие (не-HTML) таги, за исключением нескольких зарезервированных (<widget, <slot, <attr, <include, <using) представляют виджеты и точки использования слотов.

Зарезервированное слово Hybrid в списке аттрибутов любого открывающего тага означает что текст между этим тагом и соответствующим закрывающим тагом является Гибридным(Hybrid) кодом (Java кодом, смешанным с HTML элементами). В противном случае, текст интерпритируется как содержание страницы:

<p Hybrid>/*здесь пишется гибридный код, как например:*/ x=y; < br>z=h; </p>
<p> /*текст же после этого комментария идет на HTML страницу:*/ Текст </p>

HTML элементы, не допускающие текста между тагами, всегда “Гибридные”.

<table> //Таг Table всегда "hybrid"(гибридный).
for (int i=1; i<5; i++) {
<tr>
<td>...</td>
<td>...</td>
</tr>
}
</table>

Виджеты и Слоты

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

<widget name=widget1 Hybrid> // Пример определения виджета в файле widget1.widget
<attr name=attr1 type=int default=8/> // Пример определения аттрибута
... // некий код на HybridJava; продолженный после определения слота s1
<slot name=s1 Hybrid> // начало определения поименовоанного слота; “умолчательный” HybridJava код внутри
... // некий HybridJava код “по умолчанию”
<p> some text /* некий “умолчательный” HTML текст */ </p>
</slot> // конец определения поименованного слота
... // некий код на HybridJava; продолженный после определения слота s2
<slot name=s2> // начало определения поименованного слота; “умолчательный” текст документа внутри
... // некий текст HTML документа
</slot> // конец определения поименованного слота
... // и еще некий HybridJava код
<slot name=s3/> // определение слота без заполнения по умолчанию (содержания)
</widget> // конец определения виджета

Пример вызова (использования) виджета:

<widget1>
<s1> некий текст /* некий текст заполняющий документ */ </s1>
<s2 Hybrid> ... /* некий HybridJava код заполняющий страницу */ </s2>
</widget1> // слот s3 не использован вообще, но кого это волнует;

Для вызова виджета с анонимным слотом, просто:

<widget2 Hybrid> /* некий код на HybridJava */ </widget2>

Переменная определенная в теле виджета может быть “экспортирована” в слот:

<widget name=widget4 Hybrid> // определение виджета
String color =”Red“;
<slot color/> // у анонимного слота нет имени, переменная “color” экспортируется в слот
</widget> // слот s3 не использован вообще, но кого это волнует;
//------- использование:
<widget4> color=$color </widget4>// на экране браузера: color=Red

В случае рекурсии, хотя бы один из задействованных в рекурсии виджетов должен ограничивать ее глубину. Аттрибут recursion может быть задан > 1 в определении виджета или в вызове виджета. Установка recursion в определении виджета в 0 запрещает рекурсивное использование данного виджета.

Переменные

Переменные языка HybridJava в общем-то являются Java переменными. Их можно объявлять и использовать внутри Гибридных участков кода, используя стандартный синтаксис Java. Определение аттрибута виджета также создает переменную, видимую внутри тела виджета. Тип аттрибута по умолчанию String:

<attr name=attr1 type=int/> // создает целочисленную переменную variable “attr1” local to the widget
int x = 77;//традиционный (Java) способ создания переменной
System.err.println(attr1 + x);

Переменные могут быть использованы в тагах вызова виджета:

<MyWidget attr1=x> // переменной (аттрибуту) “attr1” виджета присвоено значение x (77)
    //здесь пишется заполнение анонимного слота виджета “MyWidget”
</MyWidget>

Также (предворенные символом $) в содержимом HTML документа и в аттрибутах HTML тагов:

<p > доход составляет $x баксов </p > // значение переменной x печатается в HTML
<input type=button value=”$x>// значение переменной x печатается в пространство для значения аттрибута HTML

Дополнительная точка с запятой может быть необходима:

String prefix = flag ? “кон” : “контра”;
<p> Какая замечательная $prefix;цепция!</p>

Ограничение: в отличие от Java, в HybridJava знак доллара ($) не может быть частью идентификатора

Переменные определенные в странице доступны в любом виджете вызываемом этой страницей прямо или косвенно. Переменные определенные внутри виджета доступны лишь в коде виджета.

Язык Выражений

Выражение на языке Java заключенное в ${ ... } скобки вычисляется во время исполнения и его значение используется согласно контексту выражения. Значение выражения подставляется в генерируемый текст HTML документа, в аттрибут HTML элемента или передан в виджет

Псевдо-переменная $#

Фреймворк подменяет эту переменную уникальным идентификатором компоненты.

Прочие Свойства

Java комментарии попадают в сгенерированный Java код. HTML комментарии появляются в HTML страницах. Знаки<,> и & в содержимом HTML переводятся в & lt; , &gt; и &amp; . $// и $/* эскейпируют начала комментариев; $< эскейпирует то, что не должно быть распознано как начало HTML или виджет тага (а также <widget, <slot, <attr и <!--). $$ эскейпирует $.

В языке HybridJava предложения import и implements помещаются среди других Java предложений. Компилятор собирает import и implements стейтменты в генерируемый исходник класса Java страницы.

Предполагается, что страницы и виджеты принадлежат пакетам в том же смысле что и Java классы. Чтобы использовать виджет из пакета, иного нежели пакет текущей страницы или виджета, используйти аттрибут use или таг using:

<widget7 use=com.HybridJava.X>
<using com.HybridJava.X/>

Виджеты из пакета com.HybridJava.Lib доступны по умолчанию, если не переопределены.

Предопределенный виджет <Include с аттрибутом file вставляет содержимое файла в генерируемый Java код так, что оно в конце концов попадает в HTML страницу. Файл может быть интерпретирован в зависимости от его расширения и других аттрибутов виджета <Include .

В HybridJava нет определений классов и методов, но Вы можете использовать классы и методы определенные в других местах.

Идентификация

Обрабатывая идентификатор в файле .widget компилятор HybridJava сначала пытается найти его определение в HybridJava коде виджета. Затем - среди аттрибутов виджета. Затем, он ищет в экспортах соответствующих слотов. Затем он проверяет переменные инстанса класса состояния компоненты. Наконец, проверяется существует ли подходящее определение в инстансе класса состояния аппликации (AS). Иначе, идентификатор(в текущей имплементации) оставляется для обработки javac. Последнее может привести к обнаружению определения в Hybrid (Java) коде страницы .page или в инстансе класса состояния страницы (*_PS). Наконец, javac пробует разрешить идентификатор в импортированных классах. Процесс разрешения идентификатора из файла .page происходит схожим образом, за исключением того что имеет меньшее количество шагов.

Структура Директорий

Файлы .page следует располагать в директории pages\ в поддиректории пакета (т.е. pages\com\HybridJava\Lib\Page1.page). Аналогично, файлы .widget должны находиться под директорией widgets\. Так что в HybridJava полные имена страниц и виджетов включают имя пакета.

Имплементация запускаемая из командной строки читает файлы .page и .widget из директорий pages\ и widgets\ , и генерирует файлы .java в поддиректории gen\; один .java файл соответствует одной странице. Например, для страницы X.page, имя генерируемого файла будет X_P.java.

I18N

Текущая имплементация компилятора HybridJava воспринимает файлы с не-ASCII символами представленными в формате \uffff . Такие файлы могут быть сгенерированы из исходников на Unicode с использованием стандартной утилиты native2ascii. Таким образом интернационализация в основном происходит во время билда.

О так называемом "разделении"

Резонно стремиться к разделению между слоем презентации и бизнес слоем (а также другими слоями). Однако многие стремятся к разделению Java и HTML, что не есть то же самое.

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

Не следует путать возможность с необходимостью. Если вы не хотите смешивать Java и HTML, просто этого не делайте. Это скорее относится к вашей культуре программирования, а не к самому языку. Используя язык HybridJava (что верно и для любого другого языка программирования) можно программировать разными способами. В частности, в примере Sample Application все страницы и большинство виджетов написаны в стиле "разделения". Лишь несколько низкоуровневых виджетов используют элементы Java синтаксиса, например виджет <If. В обмен на это HybridJava (в отличии от JSP  +  JSTL) вовсе не имеет встроенных тагов - вы можете написать их сами.


© 2012 HybridServerPages Group. Все права защищены.