Глава JSP.10

API Развёртывания Тэгов


В этой главе описываются обработчики тэгов и другие классы развёртывания тэгов, а также методы доступа к файлам Tag Library Descriptor/Дескриптора Библиотеки Тэгов. Это дополняет предыдущую главу  описанием формата файлов Tag Library Descriptor и их использование в директивах taglib.

Эта глава включает содержимое, сгенерированное автоматически из javadoc, внедрённых в реальные Java-классы и интерфейсы. Это позволяет создавать единый авторизованный документ-спецификацию.

Специальные акции могут использоваться авторами и утилитами авторизации JSP для упрощения процесса написания JSP-страниц. Специальные акции могут быть пустыми или непустыми акциями.

Пустой тэг не имеет тела. Есть два эквивалентных синтаксиса, один - с отдельными начальным и конечным тэгами, другой - в котором начальный и конечный тэги скомбинированы в один тэг.

Следующие два пример идентичны:


<x:foo att="myObject" />

<x:foo att="myObject" ></foo>


Непустой тэг имеет начальный тэг, тело и конечный тэг.


Пример-прототип имеет форму:


<x:foo att="myObject" >

BODY

</x:foo/>


Спецификация JavaServer Pages(тм) (JSP) 1.2 предоставляет переносимый механизм для описания библиотек тэгов, включающий:


Данная глава разбита на три раздела:

Первый раздел представляет базовые классы обработчика тэга.
Во втором разделе описаны более сложные обработчики тэга, которым необходим доступ к обсчёту их тела.
Последний раздел посвящён вопросам этапа/времени трансляции.

JSP.10.1 Простые Обработчики Тэгов

Этот раздел вводит понятие обработчика тэга и описывает простейшие типы обработчика тэга.

Обработчик Тэга/Tag Handler

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

Обработчик тэга создаётся первоначально с использованием нулевого аргумента конструктора в соответствующем классе; метод java.beans.Beans.instantiate() не используется.

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

setter-метод используется для установки свойств, обнаруженных с помощью машины интроспекции JavaBeans.

Протокол, поддерживаемый обработчиком тэга, даёт возможность передавать параметры, обсчитывать и пересчитывать тело акции и получать доступ к объектам и другим обработчикам тэгов в JSP-странице.

Экземпляр обработчика тэга отвечает за обработку тэга на этапе запроса. В обязанности JSP-контейнера входит запуск этого процесса.

Дополнительная информация времени трансляции, ассоциированная с акцией, указывает имена каких-либо переменных скриптинга, которые она (акция) может вводить, их типы и области видимости.

В определённые моменты JSP-контейнер будет автоматически синхронизировать информацию Page-Context с переменными на языке скриптинга, чтобы они могли стать доступными непосредственно через элементы скриптинга.

Свойства

Обработчик тэга имеет несколько свойств.

Все обработчики тэгов имеют свойство pageContext для JSP-страницы, на которой находится тэг, и свойство parent для обработчика тэга ближайшей внешней/содержащей акции. Отдельные классы обработчика тэга могут иметь дополнительные свойства.

Все атрибуты специальной акции обязаны быть свойствами компонента JavaBeans, хотя некоторые свойства не могут экспонироваться в качестве атрибутов. Атрибуты, видимые JSP-транслятору, это в точности те атрибуты, которые перечислены в Дескрипторе Обработчика Тэга/(TLD).

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

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

Неспецифицированные атрибуты/свойства не должны использоваться (через setter-метод).

После того как свойство установлено, оно считается постоянным, так что, если JSP-контейнер утверждает, что свойство уже установлено в данном экземпляре обработчика тэга, оно не должно устанавливаться ещё раз (дополнительно).

Пользовательский код имеет доступ к информации свойства и может модифицировать внутреннее состояние обработчика тэга, начиная с первого метода акции (doStartTag) до последнего метода данной акции (doEndTag или doFinally - для обработчиков тэгов, реализующих TryCatchFinally).

Обработчик Тэга как Объект, Обслуживаемый Контейнером

Поскольку обработчик тэга является объектом, обслуживаемым контейнером, контейнер должен обслуживать его ссылки; точнее, пользовательский код не должен сохранять ссылки на обработчик тэга, за исключением ссылок между стартом первого метода акции (doStartTag()) и концом последнего метода акции (doEndTag() или doFinally() - для тэгов, реализующих TryCatchFinally).

Эти ограничения на ссылки на объекты обработчика тэга и на модификацию свойств атрибутов дают JSP-контейнеру относительную свободу для эффективного обслуживания объектов обработчика тэга для достижения различных целей. Например, контейнер может реализовывать различные стратегии пулинга/pooling (создания пула) для минимизации затрат на создание, или может осуществлять установку свойств для уменьшения затрат, когда обработчик тэга находится внутри другого повторяющегося/iterative тэга.

Соглашения

Обработчик тэга реализует акцию; JSP-контейнер обязан выдерживать конверсии типов, описанные в Разделе 2.13.2, при присвоении значений атрибутам акции.

Пустые и Непустые Акции

Пустая акция не имеет тела; она может использовать один или два синтаксиса: <foo/> или <foo></foo>. Поскольку пустые акции не имеют тела, методы, имеющие отношение к работе с телом, не вызываются.

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

Непустая акция имеет тело.

Интерфейс Tag

Обработчик тэга, который "не хочет" обрабатывать своё тело, может просто реализовывать интерфейс Tag. Обработчик тэга может "не хотеть" обрабатывать своё тело, если это пустой тэг, или из-за того, что тело просто "передаётся (дальше)/passed through".

Интерфейс Tag имеет методы предоставления информации о контексте страницы экземпляру Обработчика Тэга, методы обслуживания жизненного цикла обработчиков тэгов и два основных метода для выполнения акции: doStartTag()и doEndTag().

Метод doStartTag() вызывается при обнаружении начального тэга, и его return-значение указывает, должно ли тело/body (если имеется) быть пропущено, или вычислено и передано текущему потоку response.

Метод doEndTag() вызывается при обнаружении конечного тэга; его return-значение указывает, должно ли продолжаться обсчитывание оставшейся части страницы, или нет.
Если в процессе обсчёта тела тэга обнаружено исключение, метод doEndTag не будет выполняться. См. в тэге TryCatchFinally методы, которые гарантированно выполняются.

Интерфейс IterationTag

Интерфейс IterationTag используется для повторяющихся вычислений тела специальной акции.

Этот интерфейс имеет единственный метод - doAfterBody(), который вызывается после каждого вычисления тела для определения необходимости дальнейших вычислений.

Повторение вычисления запрашивается значением 2, которое в JSP 1.1 определено как BodyTag.EVAL_BODY_TAG. Это константное значение сохранено в JSP 1.2 (для полной обратной совместимости), но, для улучшения ясности кода, имеется и новое имя: IterationTag.EVAL_BODY_AGAIN.
Для остановки итерации возвращаемое значение должно быть 0, то есть Tag.SKIP_BODY.

Базовый Класс TagSupport

Класс TagSupport является базовым классом, используемым при реализации интерфейсов Tag или IterationTag.

JSP.10.1.1 Интерфейс Tag


Синтаксис


public interface Tag


Все Известные Субинтерфейсы: BodyTag, IterationTag


Описание


Это интерфейс простого обработчика тэга, который не хочет манипулировать своим содержимым. Интерфейс Tag определяет базовый протокол между обработчиком Tag и классом реализации JSP-страницы. Он определяет жизненный цикл и методы, вызываемые начальным и конечным тэгами.


Свойства


Интерфейс Tag специфицирует setter и getter-методы для основных свойств pageContext и parent. Объект реализации JSP-страницы вызывает setPageContext и setParent в этом порядке до вызова doStartTag() или doEndTag().


Методы


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


Жизненный цикл


Детали жизненного цикла описываются ниже диаграммой перехода, со следующими комментариями:


После того как все вызовы обработчика тэга выполнены, в нём вызывается метод release.
После вызова метода release, принимается, что все свойства, включая parent и pageContext, устанавливаются в неспецифицированное значение/unspecified. Компилятор страницы гарантирует, что release() будет вызван в обработчике Tag, до того как обработчик будет освобождён для GC.


Пустые и Непустые Акции
 

Если файл TagLibraryDescriptor указывает, что акция обязана всегда быть пустой акцией, через <body-content> - "empty", тогда метод doStartTag() обязан возвращать SKIP_BODY. В ином случае, метод doStartTag() может вернуть SKIP_BODY или EVAL_BODY_INCLUDE.

Если возвращён SKIP_BODY, тело, если имеется, не обсчитывается.

Если возвращён EVAL_BODY_INCLUDE, тело обсчитывается и "передаётся" текущему out/выводу.

JSP.10.1.1.1 Поля


public static final int EVAL_BODY_INCLUDE

  Вычисляет тело в существующем потоке out. Верное return-значение для doStartTag.


public static final int EVAL_PAGE

  Продолжить вычисление страницы. Верное return-значение для doEndTag().


public static final int SKIP_BODY

  Пропустить вычисление тела. Верное return-значение для doStartTag и doAfterBody.


public static final int SKIP_PAGE

  Пропустить оставшуюся часть страницы. Верное return-значение для doEndTag.

JSP.10.1.1.2 Методы


public int doEndTag()


Обрабатывает конечный тэг данного экземпляра. Этот метод вызывается объектом реализации JSP-страницы для всех обработчиков Tag. Этот метод будет вызываться после возвращения из doStartTag. Тело акции может или может не вычисляться, в зависимости от return-значения doStartTag.

Если этот метод возвращает EVAL_PAGE, остаток страницы продолжит вычисляться.

Если этот метод возвращает SKIP_PAGE, остаток страницы не вычисляется, и запрос выполняется. Если этот запрос был направлен или включён из другой страницы (или Servlet), выполняется вычисление только текущей страницы. JSP-контейнер будет ресинхронизировать любые значения переменных, которые обозначены таковыми в TagExtraInfo, после вызова doEndTag().


Вызывает:JspException, JspException


public int doStartTag()


Обрабатывает начальный тэг данного экземпляра. Этот метод вызывается объектом реализации JSP-страницы.
Метод doStartTag принимает, что свойства pageContext и parent установлены. Он также принимает, что любые свойства, экспонированные как атрибуты, также установлены. В момент вызова этого метода тело ещё не вычислено.

Этот метод возвращает Tag.EVAL_BODY_INCLUDE или Body-Tag.EVAL_BODY_BUFFERED для обозначения того, что тело акции должно быть повторно вычислено, или SKIP_BODY - для обозначения противоположного.

Если Tag возвращает EVAL_BODY_INCLUDE, результат вычисления тела (если имеется) включается в текущий "out" JspWriter, когда он появляется. а затем вызывается doEndTag().


BodyTag.EVAL_BODY_BUFFERED
является единственно верным значением, если обработчик тэга реализует BodyTag .


JSP-контейнер будет ресинхронизировать любые значения переменных, которые обозначены как таковые в TagExtraInfo, после вызова doStartTag().


Вызывает: JspException, JspException


См. также: BodyTag


public Tag getParent()


Получает родителя (ближайшего внешнего/содержащего обработчика тэга) для данного обработчика тэга.

Метод getParent() может использоваться для навигации по структуре вложенного обработчика тэга во время прогона для взаимодействия специальных акций; например, метод find-AncestorWithClass() в TagSupport предоставляет подходящий способ выполнения этого.


В текущей версии спецификации имеется только один формальный способ указания на рассматриваемый тип обработчика тэга: его класс реализации, описанный в субэлементе tag-class элемента tag. Он разворачивается неформальным способом, давая разрешение автору библиотеки тэгов указывать рассматриваемый тип в описании субэлемента. Этот тип должен быть подтипом класса реализации обработчика тэга или void. Это дополнительное ограничение может быть обработано специализированным контейнером, который знает об этой специфической библиотеке тэгов, как в случае со стандартной библиотекой тэгов JSP.


public void release()


Вызывается для освобождения состояния/release state. Компилятор страницы гарантирует, что объект реализации JSP-страницы будет вызывать этот метод для всех обработчиков тэгов, но между ними может быть несколько вызовов doStartTag и doEndTag.


public void setPageContext(PageContext pc)


Устанавливает текущий контекст страницы. Этот метод вызывается объектом реализации JSP-страницы до вызова doStartTag().


Это значение *не* переустанавливается методом doEndTag() и обязано быть переустановлено явно реализацией страницы, если оно изменяется между вызовами doStartTag().


pc - Контекст страницы для данного обработчика тэга.


public void setParent(Tag t)


Устанавливает родителя (ближайшего внешнего обработчика тэга) для данного обработчика тэга. Вызывается объектом реализации JSP-страницы до вызова doStartTag().


Это значение *не* переустанавливается методом doEndTag() и обязано быть переустановлено явно реализацией страницы.


Параметры:

t - тег-родитель или null.

JSP.10.1.2 IterationTag


Синтаксис


public interface IterationTag extends Tag


Все Известные Субинтерфейсы: BodyTag


Все Суперинтерфейсы: Tag


Все Известные Реализующие Классы: TagSupport


Описание


Интерфейс IterationTag расширяет интерфейс Tag через определение одного дополнительного метода, управляющего повторными вычислениями его тела.

Обработчик тэга, реализующий IterationTag, рассматривается как обработчик, реализующий Tag через методы doStartTag() и doEndTag(). IterationTag предоставляет новый метод: doAfterBody().


Метод doAfterBody() вызывается после каждого цикла итерации - вычисления тела для управления последующими вычислениями тела.

Если doAfterBody() возвращает IterationTag.EVAL_BODY_AGAIN, тогда тело снова будет вычисляться.
Если doAfterBody() возвращает Tag.SKIP_BODY, тогда тело будет пропущено и вместо него будет обсчитываться doEndTag().


Свойства


Новых свойств, в дополнение к уже имеющимся в Tag, нет.


Методы


Имеется один новый метод: doAfterBody().


Жизненный цикл


Жизненный цикл показан на диаграмме переноса. Исключения, вызываемые в процессе обсчёта doStartTag(), BODY и doAfterBody(), прерывают последовательность выполнения и помещаются на верх стэка, если только обработчик тэга не реализует интерфейс TryCatchFinally; см. детали об этом интерфейсе.
 


Пустые и Непустые Акции


Если TagLibraryDescriptor-файл указывает, что тело всегда обязано иметь пустую акцию (когда вхождение <body-content> установлено в "empty"), тогда метод doStartTag() обязан возвращать SKIP_BODY. В ином случае метод doStartTag() может возвратить SKIP_BODY или EVAL_BODY_INCLUDE.


Если возвращено SKIP_BODY, тело не обсчитывается и вызывается doEndTag().

Если возвращено EVAL_BODY_INCLUDE, тело обсчитывается и "передаётся" текущему out, затем вызывается doAfterBody() и, после 0 или более итераций, вызывается doEndTag().

JSP.10.1.2.3 Поля


public static final int EVAL_BODY_AGAIN


Запрашивает повторение обсчёта некоторого тела/body. Возвращается методом doAfterBody. Для совместимости с JSP 1.1 значение должно тщательно подбираться, чтобы быть тем же самым, что и в, теперь не рекомендуемом, BodyTag.EVAL_BODY_TAG.

JSP.10.1.2.4 Методы


public int doAfterBody()


Осуществляет (пере)обсчёт тела. Этот метод вызывается объектом реализации JSP-страницы после каждого обсчёта тела в объекте BodyEvaluation. Этот метод не вызывается, если нет обсчёта тела/body.


Если doAfterBody возвращает EVAL_BODY_AGAIN, происходит новый обсчёт тела (с последующим вызовом doAfterBody). Если doAfterBody возвращает SKIP_BODY, обсчёт тела больше не производится, значение out восстанавливается через использование метода popBody в pageContext, а затем вызывается doEndTag.

Повторные вызовы метода могут приводить к различным акциям, поскольку могли быть произведены какие-то изменения разделяемого статуса, или из-за внешнего вычисления. JSP-контейнер будет ресинхронизировать любые значения переменных, которые обозначены в TagExtraInfo, после вызова doAfterBody().


Возвращает: нужно ли проводить дополнительные обсчёты тела/body.


Вызывает: JspException

JSP.10.1.3 TryCatchFinally


Синтаксис


public interface TryCatchFinally


Описание


Интерфейс, в дополнение к Tag, IterationTag или BodyTag, для обработчика тэга, которому нужны дополнительные возможности для обслуживания ресурсов. Этот интерфейс предоставляет два новых метода: doCatch(Throwable) и doFinally().


Прототип вызова таков:


h = get a Tag(); // получает обработчика тэга, возможно из пула
h.setPageContext(pc); // инициализируется
h.setParent(null);
h.setFoo("foo");

// протокол вызова тэга; см. Tag.java

try {
doStartTag()...
....
doEndTag()...
}catch (Throwable t){
// реагирует на условие исключения
h.doCatch(t);
} finally {
// восстанавливает инварианты данных и освобождает вызванные ресурсы
h.doFinally();
}

... другие вызовы, возможно, с новыми setter'ами

...

h.release(); // освобождает долгосрочные ресурсы

JSP.10.1.3.5 Методы


public void doCatch(java.lang.Throwable t)


Вызывается, если возникает Throwable при обсчёте BODY внутри тэга, или любым из следующих методов: Tag.doStartTag(), Tag.doEndTag(), Iteration-Tag.doAfterBody() и BodyTag.doInitBody().


Этот метод вызывается, если Throwable возникает в одном из setter-методов.


Этот метод может вызывать исключение (то же самое или новое), которое будет затем помещено во вложенную цепь. Если исключение возникает, будет вызван doFinally().


Этот метод предназначен для использования в ответ на исключительное условие.


Параметры:


t
- Навигация вызываемого исключения по этому тэгу.


Вызывает: Throwable


public void doFinally()


Вызывается во всех случаях после doEndTag() для всех классов, реализующих Tag, IterationTag или BodyTag. Этот метод вызывается, даже если в BODY тэга возникло исключение, или в любом из следующих методов:

Tag.doStartTag(), Tag.doEndTag(), IterationTag.doAfterBody() и Body-Tag.doInitBody().


Этот метод не вызывается, если Throwable возникает в одном из setter-методов.

Этот метод не должен вызывать Exception.

Этот метод предназначен для обслуживания целостности данных при вызове и акций обслуживания ресурсов.

JSP.10.1.4 TagSupport


Синтаксис
 

public class TagSupport implements IterationTag, java.io.Serializable


Прямые Известные Подклассы: BodyTagSupport


Все Реализованные Интерфейсы: IterationTag, java.io.Serializable, Tag


Описание


Базовый класс для определения новых обработчиков тэгов, реализующих Tag.


Класс TagSupport является служебным классом, предназначенным для использования в качестве базового класса для новых обработчиков тэгов. Класс TagSupport реализует интерфейсы Tag и IterationTag и добавляет дополнительные удобные методы, включая getter-методы для свойств в Tag. TagSupport имеет один static-метод, который включён для облегчения координации между кооперирующимися тэгами.


Многие обработчики тэгов будут расширять TagSupport и переопределять только некоторые методы.

JSP.10.1.4.6 Поля
 

protected java.lang.String id


protected PageContext pageContext

JSP.10.1.4.7 Конструкторы


public TagSupport()


Конструктор по умолчанию, все классы должны определять только public-конструктор с той же подписью и вызывать конструктор суперкласса. Этот конструктор вызывается кодом, генерируемым JSP-транслятором.

JSP.10.1.4.8 Методы
 

public int doAfterBody()


Процессинг по умолчанию для тела/body.


Возвращает: SKIP_BODY


Вызывает: JspException


См. также: public int doAfterBody()


public int doEndTag()


Процессинг по умолчанию конечного тэга, возвращающий EVAL_PAGE.


Вызывает: JspException


См. также: public int doEndTag()


public int doStartTag()


Процессинг по умолчанию начального тэга, возвращающий SKIP_BODY.


Вызывает:JspException


См. также: public int doStartTag()


public static final Tag findAncestorWithClass(Tag from, java.lang.Class klass)


Находит экземпляр типа данного класса, который ближе всего к данному экземпляру. Этот метод использует метод getParent из интерфейса Tag. Этот метод используется для координации между кооперирующимися тэгами.

Текущая версия спецификации предоставляет только один формальный способ указания на рассматриваемый тип обработчика тэга: его класс реализации обработчика тэга, описанный в субэлементе tag-class элемента tag. Здесь выполняется неформальное расширение, позволяющее автору библиотеки тэгов указывать в субэлементе description рассматриваемый тип. Тип должен быть подтипом класса реализации обработчика тэга или void. Это дополнительное ограничение может быть выполнено специализированным контейнером, который знает об этой специфической библиотеке тэгов, как в случае со стандартной библиотекой тэгов JSP.


Если автор библиотеки тэгов предоставляет информацию о рассматриваемом типе обработчика тэга, клиентский программный код должен быть приспособлен к этому ограничению. Точнее, Class, переданный в findAncestorWithClass, должен иметь подтип рассматриваемого типа.


Параметры:


from
- Экземпляр, с которого начинать просмотр.

klass - Совпадающий подкласс Tag'а или интерфейс.

public java.lang.String getId() - Значение атрибута id этого тэга; или null.

public Tag getParent() - Ближайший экземпляр Tag'а, заключающий в себе данный экземпляр тэга.


См. также: public Tag getParent()


public java.lang.Object getValue(java.lang.String k)


Получает значение, ассоциированное с ключом/key.


Параметры:

k - Строка-ключ.


public java.util.Enumeration getValues()


Перечисляет значения, хранимые в этом обработчике тэга.


public void release()


Освобождает статус.


См. также: public void release()


public void removeValue(java.lang.String k)


Удаляет значение, ассоциированное с ключом.


Параметры:


k
- строка-ключ.


public void setId(java.lang.String id)


Устанавливает атрибут id для данного тэга.


Параметры:


id
- String для id.


public void setPageContext(PageContext pageContext)


Устанавливает контекст страницы.


Параметры:


pageContenxt
- PageContext.


См. также: public void setPageContext(PageContext pc)


public void setParent(Tag t)


Устанавливает вкладывающий тэг для данного тэга.


Параметры:


t
- родительский Tag.


См. также: public void setParent(Tag t)


public void setValue(java.lang.String k, java.lang.Object o)


Ассоциирует значение со String-ключом.


Параметры:


k
- String-ключ.

o - Ассоциируемое значение.

JSP.10.2 Обработчики Тэгов, которые хотят получить Доступ к Содержимому своего Body/Тела

Вычисление тела передаётся в объект bodyContent, который затем становится доступным обработчикам тэгов, реализующим интерфейс BodyTag. Класс BodyTag-Support даёт базовый класс, упрощающий написание этих обработчиков. Если обработчик Tag хочет иметь доступ к содержимому его тела, то он обязан реализовывать интерфейс BodyTag. Этот интерфейс расширяет IterationTag, предоставляя два дополнительных метода setBodyContent(bodyContent) и doInitBody() и ссылаясь на объект типа bodyContent.

bodyContent
это подкласс JspWriter'а, имеющий несколько дополнительных методов для конвертации его содержимого в String, вставки этого содержимого в другой JspWriter, получения Reader в его содержимое и очистки содержимого. Его семантика гарантирует, что размер буфера никогда не будет превышен.

Реализация JSP-страницы создаст bodyContent, если метод doStartTag() возвращает EVAL_BODY_BUFFERED. Этот объект будет передан методу doInitBody(); затем тело тэга будет обсчитано, и в ходе этого вычисления out будет привязан к bodyContent, только что переданному обработчику BodyTag .

Затем doAfterBody() будет обсчитан. Если этот метод вернёт SKIP_BODY, больше никаких вычислений тела выполнено не будет; если метод вернёт EVAL_BODY_AGAIN, тогда тело будет обсчитано, а doAfterBody() будет вызван вновь.

Содержимое экземпляра bodyContent остаётся доступным, пока не будет вызван его ассоциированный метод doEndBody().


Обычно bodyContent используется для извлечения его содержимого в String и последующего использования этой String в качестве значения для некоторой операции. Другой обычный способ использования - взять его содержимое и поместить его в поток вывода/out Stream, который был верным/действующим/valid в момент обнаружения тэга (который доступен из объекта PageContext, переданного обработчику в setPageContext).
 

JSP.10.2.1 bodyContent


Синтаксис


public abstract class bodyContent extends JspWriter


Описание


Инкапсулирует вычисление/обсчёт тела акции так, что доступен обработчику тэга. bodyContent является подклассом JspWriter'а.


Обратите внимание, что содержимое bodyContent'а является результатом вычисления, поэтому оно не будет содержать акций и т.п., кроме результата своих вызовов.

bodyContent
имеет методы конвертации своего содержимого в String, для чтения его содержимого, и для очистки/clear своего содержимого.

Размер буфера объекта bodyContent не ограничен. Объект bodyContent не может быть в режиме autoFlush.

Невозможно вызвать flush в объекте bodyContent, так как отсутствует фоновый/backing поток.

Экземпляры bodyContent'а создаются через вызов методов pushBody и popBody класса PageContext.

bodyContent
заключён внутри другого JspWriter'а (возможно, другого объекта bodyContent), следуя структуре их ассоциированных акций.

bodyContent
становится доступным BodyTag'у через вызов setBodyContent().

Обработчик тэга может использовать этот объект до момента вызова doEndTag().

JSP.10.2.1.9 Конструкторы


protected bodyContent(JspWriter e)


Protected-конструктор. Несвязанный буфер, без autoflushing/автооочистки.

JSP.10.2.1.10 Методы
 

public void clearBody()


Очищает body без вызова исключений.


public void flush()


Переопределённый таким образом flush() не допускается. Нельзя зачищать bodyContent, поскольку позади него отсутствует фоновый/backing поток.


Переопределяет: public abstract void flush() в классе JspWriter


Вызывает: IOException


public JspWriter getEnclosingWriter()


Получает содержащий JspWriter.


Возвращает: содержащий JspWriter, переданный на этапе конструирования.


public abstract java.io.Reader getReader()


Возвращает: значение данного bodyContent как Reader.


public abstract java.lang.String getString()


Возвращает: значение данного bodyContent как String.


public abstract void writeOut(java.io.Writer out)


Записывает содержимое данного bodyContent в Writer. Подклассы могут оптимизировать общие патэрны вызова.


Параметры:


out
- writer, в который помещается содержимое вычисления этого body.


Вызывает: IOException

JSP.10.2.2 BodyTag


Синтаксис


public interface BodyTag extends IterationTag


Все Суперинтерфейсы: IterationTag, Tag


Все Известные Реализующие Классы: BodyTagSupport


Описание


Интерфейс BodyTag расширяет IterationTag путём определения дополнительных методов, позволяющих обработчику тэга манипулировать содержимым, обсчитывая его тела.

Обработчик тэга отвечает за обработку содержимого body. Например, обработчик тэга может взять содержимое тела, конвертировать его в String путём использования метода bodyContent.getString и его последующего использования. Либо обработчик тэга может взять тело содержимого и записать его в содержащий JspWriter, используя метод bodyContent.writeOut.


Обработчик тэга, реализующий BodyTag, рассматривается как обработчик, реализующий IterationTag, за исключением того, что метод doStartTag может возвратить SKIP_BODY, EVAL_BODY_INCLUDE или EVAL_BODY_BUFFERED.


Если возвращено EVAL_BODY_INCLUDE, вычисление проводится как в IterationTag.


Если возвращено EVAL_BODY_BUFFERED, будет создан объект bodyContent (в коде, генерируемом JSP-компилятором) для захвата вычисления тела.


Код, генерируемый JSP-компилятором, получает объект bodyContent через вызов метода pushBody из текущего pageContext, который дополнительно даёт эффект сохранения предыдущего значения out. Компилятор страницы возвращает этот объект через вызов метода popBody класса PageContext; этот вызов также восстанавливает значение out.


Этот интерфейс предоставляет одно новое свойство с setter-методом и новый метод акции.


Свойства


Имеется новое свойство: bodyContent, для получения объекта bodyContent, где объект реализации JSP-страницы будет размещать вычисление/обсчёт (и повторный обсчёт, если нужно) тела.

setter
-метод (setBodyContent) будет вызван только в том случае, если doStartTag() возвратит EVAL_BODY_BUFFERED.


Методы


В дополнение к setter-методу свойства bodyContent есть новый метод акции: doInitBody(), который вызывается сразу после setBodyContent() и до обсчёта тела. Этот метод вызывается только в том случае, если doStartTag() возвращает EVAL_BODY_BUFFERED.


Жизненный цикл


Детали жизненного цикла даны ниже на диаграмме переноса. Исключения, вызываемые в процессе вычислений doStartTag(), setBodyContent(), doInit-Body(), BODY, doAfterBody(), прерывают выполнение и помещаются на верх стэка, если только обработчик тэга не реализует интерфейс TryCatchFinally; см. детали об этом интерфейсе.
 


Пустые и Непустые Акции


Если TagLibraryDescriptor-файл указывает, что акция всегда обязана иметь пустую акцию (когда вхождение <body-content> установлено в "empty"), тогда метод doStartTag() обязан возвращать SKIP_BODY. В ином случае метод doStartTag() может возвратить SKIP_BODY, EVAL_BODY_INCLUDE или EVAL_BODY_BUFFERED.

Если возвращено SKIP_BODY, тело не обсчитывается и вызывается doEndTag().

Если возвращено EVAL_BODY_INCLUDE, setBodyContent() не вызывается, doInitBody() не вызывается, тело обсчитывается и "передаётся" текущему out, затем вызывается doAfterBody() и, после 0 или более итераций, вызывается doEndTag().


Если возвращено EVAL_BODY_BUFFERED, setBodyContent() вызывается, doInit-Body() вызывается, тело обсчитывается, вызывается doAfterBody() и, после 0 или более итераций, вызывается doEndTag().

JSP.10.2.2.11 Поля


public static final int EVAL_BODY_BUFFERED


Запрашивается создание нового буфера, bodyContent, в котором происходит обсчёт тела данного тэга.

Возвращается из doStartTag, если класс реализует BodyTag.

Неверным является значение doStartTag, если класс не реализует BodyTag.


public static final int EVAL_BODY_TAG


Не рекомендуется. Так как Java JSP API 1.2 использует BodyTag.EVAL_BODY_BUFFERED или IterationTag.EVAL_BODY_AGAIN.


Не рекомендуемая для использования константа, которая имеет то же значение, что и EVAL_BODY_BUFFERED и EVAL_BODY_AGAIN. Помечена как не рекомендуемая с целью продвижения этих двух различных терминов, которые являются более описательными.

JSP.10.2.2.12 Методы


public void doInitBody()


Подготавливает обсчёт/вычисление тела/body. Этот метод вызывается объектом реализации JSP-страницы после setBodyContent и до первого вычисления тела. Этот метод не вызывается для пустых тэгов или непустых тэгов, чей метод doStartTag() возвращает SKIP_BODY или EVAL_BODY_INCLUDE.

JSP-контейнер будет ресинхронизировать любые значения переменных, которые обозначены как таковые в TagExtraInfo, после вызова doInitBody().


Вызывает:JspException


public void setBodyContent(bodyContent b)


Устанавливает свойство bodyContent. Этот метод вызывается объектом реализации JSP-страницы максимум один раз на один вызов акции. Этот метод будет вызван до doInitBody. Этот метод не будет вызван для пустых тэгов и для непустых тэгов, чей метод doStartTag() возвращает SKIP_BODY или EVAL_BODY_INCLUDE.
Если setBodyContent вызывается, значение неявного объекта out уже было изменено в объекте pageContext. Передаваемый объект bodyContent не будет содержать данных, но может использоваться повторно (и очищаться) после некоторого предыдущего вызова.

Объект bodyContent доступен с соответствующим содержимым, пока не вызван метод doEndTag, после чего он может быть использован повторно.


Параметры:


b - bodyContent

JSP.10.2.3 BodyTagSupport


Синтаксис


public class BodyTagSupport extends TagSupport implements BodyTag


Все Реализованные Интерфейсы: BodyTag, IterationTag, java.io.Serializable, Tag


Описание


Базовый класс для определения обработчиков тэгов, реализующих BodyTag.

Класс BodyTagSupport реализует интерфейс BodyTag и добавляет несколько удобных методов, включая getter-методы для свойства bodyContent и методы для получения предыдущего out JspWriter.

Многие обработчики тэгов будут расширять BodyTagSupport и переопределять только несколько методов.

JSP.10.2.3.13 Поля


protected bodyContent bodyContent

JSP.10.2.3.14 Конструкторы


public BodyTagSupport()


Конструктор по умолчанию, все подклассы должны определить public-конструктор с той же подписью и вызвать конструктор суперкласса. Этот конструктор вызывается кодом, генерируемым JSP-транслятором.

JSP.10.2.3.15 Методы

public int doAfterBody()


После вычисления/обсчёта тела: не выполнять повторного обсчёта и продолжать разбор страницы. С данными bodyContent по умолчанию ничего не делается (если они имеются).


Переопределяет: public int doAfterBody() в классе TagSupport


Возвращает: SKIP_BODY


Вызывает: JspException


public int doEndTag()


Процессинг по умолчанию конечного тэга, возвращающий EVAL_PAGE.


Переопределяет: public int doEndTag() в классе TagSupport


Возвращает: EVAL_PAGE


Вызывает: JspException


public void doInitBody()


Подготавливает обсчёт/вычисление тела/body сразу перед первым вычислением тела: нет акции.


Вызывает: JspException


public int doStartTag()


Процессинг по умолчанию начального тэга, возвращающий


Переопределяет: public int doStartTag() в классе TagSupport.


Возвращает: EVAL_BODY_BUFFERED;


Вызывает:JspException


public bodyContent getBodyContent()


Получает текущий bodyContent.


Возвращает: содержимое тела.


public JspWriter getPreviousOut()


Получает окружающий out JspWriter.


Возвращает: содержащий JspWriter, из bodyContent.


public void release()


Освобождает статус.


Переопределяет: public void release() в классе TagSupport.


public void setBodyContent(bodyContent b)


Подготавливает для обсчёта тела: прячет bodyContent.


Параметры: b - bodyContent

JSP.10.3 Пример Работы с Аннотированным Обработчиком Тэга

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

Есть и другие стратегии, которым можно следовать.

В данном примере мы принимаем, что x:iterate это тег итерации, а x:doit и x:foobar - простые тэги. Мы также принимаем, что x:iterate и x:foobar реализуют интерфейс TryCatchFinally, а x:doit - не реализует его.


<x:iterate src="foo">
  <x:doit att1="one" att2="<%=1 +1 %>"/>
  <x:foobar />
  <x:doit att1="one" att2="<%=2 +2 %>"/>
</x:iterate>
<x:doit att1="one" att2="<%=3 +3 %>"/>


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


boolean b1, b2;
IterationTag i; // для x:iterate
Tag d; // для x:doit
Tag d; // для x:foobar
page: // лэйбл для конца страницы...
// инициализируется тэг итерации
i = get tag from pool or new();
i.setPageContext(pc);
i.setParent(null);
i.setSrc("foo");
// x:iterate implements TryCatchFinally
try {
    if ((b1 = i.doStartTag()) == EVAL_BODY_INCLUDE) {
         // инициализируется тэг doit
         // код выводится из цикла для показа
         d = get tag from pool or new();
         d.setPageContext(pc);
         d.setParent(i);
         d.setAtt1("one");
    loop:
      while (1) do {
      // Игнорирую символы новой строки...
      // два вызова, сплавленные вместе
      // первый вызов x:doit
      d.setAtt2(1+1);
      if ((b2 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
          // ничего
      } else if (b2 != SKIP_BODY) {
         // Q? ошибка протокола ...
      }
      if ((b2 = d.doEndTag()) == SKIP_PAGE) {
           break page; // выполняется им.
      } else if (b2 != EVAL_PAGE) {
           // Q? ошибка протокола
      }

// вызов x:foobar
      f = get tag from pool or new();
      f.setPageContext(pc);
      f.setParent(i);
      // x:foobar implements TryCatchFinally
      try {
         if ((b2 = f.doStartTag()) == EVAL_BODY_INCLUDE) {
             // ничего
         } else if (b2 != SKIP_BODY) {
            // Q? ошибка протокола
         }
         if ((b2 = f.doEndTag()) == SKIP_PAGE) {
             break page; // выполняется им.
         } else if (b2 != EVAL_PAGE) {
            // Q? ошибка протокола
         }
} catch (Throwable t) {
         f.doCatch(t); // отловлено, может быть повторно отловлено!
} finally {
         f.doFinally();
}
// помещает f обратно в пул

// второй вызов x:doit
d.setAtt2(2+2);
if ((b2 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
    // ничего
} else if (b2 != SKIP_BODY) {
   // Q? ошибка протокола
}
if ((b2 = d.doEndTag()) == SKIP_PAGE) {
    break page; // выполняется им.
} else if (b2 != EVAL_PAGE) {
   // Q? ошибка протокола
}
if ((b2 = i.doAfterBody()) == EVAL_BODY_AGAIN) {
   break loop;
} else if (b2 != SKIP_BODY) {
   // Q? ошибка протокола
}

// цикл
}
} else if (b1 != SKIP_BODY) {
// Q? ошибка протокола
}

// конец IteratorTag ...
if ((b1 = i.doEndTag()) == SKIP_PAGE) {
   break page; // выполняется им.
} else if (b1 != EVAL_PAGE) {
   // Q? ошибка протокола
}

// третий вызов
// этот обработчик тэга может быть повторно использован из предыдущего.
d = get tag from pool or new();
d.setPageContext(pc);
d.setParent(null);
d.setAtt1("one");
d.setAtt2(3+3);
if ((b1 = d.doStartTag()) == EVAL_BODY_INCLUDE) {
   // ничего
} else if (b1 != SKIP_BODY) {
   // Q? ошибка протокола
}
if ((b1 = d.doEndTag()) == SKIP_PAGE) {
   break page; // выполняется им.
} else if (b1 != EVAL_PAGE) {
   // Q? ошибка протокола
}
}catch (Throwable t){
i.doCatch(t); // отловлено, может быть повторно отловлено!
} finally {
i.doFinally();
}

JSP.10.4 Кооперирующиеся Акции

Акции могут кооперироваться с другими акциями и с кодом скриптинга разными способами.

PageContext


Часто две акции в JSP-странице нужно скооперировать: когда, возможно, одна акция создаёт серверный объект, доступ к которому осуществляет вторая акция. Один из механизмов реализации этого - дать объекту имя внутри JSP-страницы; первая акция создаст объект и ассоциирует имя с ним, а вторая акция будет использовать это имя для запроса объекта.

Например, в следующем JSP-фрагменте акция foo может создать серверный объект и дать ему имя "myObject". Затем акция bar может получить доступ к этому серверному объекту и выполнить какое-нибудь действие.


<x:foo id="myObject" />

<x:bar ref="myObjet" />


В JSP-реализации отображение "имя"->значение хранится в неявном объекте pageContext. Этот объект передаётся по кругу через экземпляры обработчика Tag так, что он (объект) может использоваться для передачи информации: всё, что необходимо, это знать имя, под которым информация хранится в pageContext.


Стэк Времени Прогона/Runtime Stack

Альтернативой явной передаче информации через именованный объект является неявная координация на базе синтаксической видимости. Например, в следующем JSP-фрагменте акция foo могла бы создать серверный объект; затем вложенная акция bar могла бы получить доступ к этому серверному объекту. Этот объект не именован внутри pageContext: он может быть найден, поскольку конкретный элемент foo является ближайшим содержащим экземпляром известного типа элемента.


<foo>

<bar/>

</foo>


Эта функциональность поддерживается через BodyTagSupport.findAncestorWithClass(Tag, Class), который использует ссылку на родительский тэг, сохраняемую каждым экземпляром Tag, что эффективно представляет стэк выполнения времени/этапа прогона.

JSP.10.5 Классы Времени Трансляции

Следующие классы используются на этапе трансляции.


Tag
-отображение, Tag-имя

Директива taglib вводит библиотеку тэгов и ассоциирует с ней префикс. TLD, ассоциированный с библиотекой, ассоциирует классы обработчика Tag (плюс другая информация) с именами тэгов. Эта информация используется для ассоциирования Tag-класса, префикса и имени с каждым элементом специальной акции, появляющимся на JSP-странице.

На этапе выполнения реализация JSP-страницы будет использовать доступный экземпляр Tag с соответствующими установками свойств, а затем следовать протоколу, описанному интерфейсами Tag, IterationTag, BodyTag и TryCatchFinally. Реализация гарантирует, что все экземпляры обработчика тэга инициализируются и высвобождаются, но реализация может принимать, что предыдущие установки сохраняются обработчиком тэга, чтобы уменьшить затраты на этапе прогона.


Переменные Скриптинга

JSP поддерживает переменные скриптинга, которые могут объявляться внутри одного скриптлета и использоваться в другом. JSP-акции также можно использовать для определения переменных скриптинга, чтобы использовать их затем в элементах скриптинга или в других акциях. Это особенно применимо в некоторых случаях; например, стандартная акция jsp:useBean может определять объект, который позднее используется через переменную скриптинга.

В некоторых случаях информация переменных скриптинга может быть описана непосредственно в TLD, используя элементы. Особый случай - типичная итерация атрибута &quotid". В других случаях логика, определяющая определение экземпляром акции переменной скриптинга, может быть довольно сложной, и имя класса TagExtraInfo используется вместо данного в TLD. Метод getVariableInfo этого класса используется во время трансляции для получения информации о каждой переменной, которая будет создана во время запроса, когда данная акция выполняется. Метод передаётся в TagDat-экземпляр, содержащий значения атрибутов времени трансляции.

Проверка/Validation

TLD-файл содержит несколько частей информации, которая используется для проверки синтаксиса на этапе трансляции. Он содержит также два расширяемых механизма проверки: класс TagLibraryValidator может использоваться для проверки всей JSP-страницы, а класс TagExtraInfo может использоваться для проверки специфической акции. В некоторых случаях дополнительная проверка на этапе запроса будет выполняться динамически внутри методов в экземпляре Tag. Если обнаружена ошибка, может быть вызван экземпляр JspTagException. Если ошибка не выловлена, этот объект будет вызывать механизм errorpage JSP.


TagLibraryValidator
является дополнением к спецификации JSP 1.2 и заканчивается очень открыто, будучи значительно более мощным, чем механизм TagExtraInfo. JSP-страница представляется через объект PageData, который абстрагирует XML-просмотр JSP-страницы. Экземпляр PageData будет предоставлять InputStream (только для чтения) в странице. Последующие спецификации могут добавить другие просмотры страницы (DOM, SAX, JDOM являются кандидатами). В настоящее время эти просмотры могут генерироваться из InputStream и, возможно, кэшироваться для повышения производительности (вызов просмотра страницы делается "только для чтения").

JSP-контейнер может по выбору поддерживать атрибут jsp:id для более качественной проверки ошибок. Если атрибут поддерживается, контейнер будет отслеживать JSP-страницы по мере передачи контейнеру и назначать каждому элементу уникальный идентификатор "id", который передаётся как значение атрибута jsp:id. Каждый XML-элемент, доступный в XML-просмотре, будет расширен этим атрибутом. TagLibraryValidator может затем использовать этот атрибут в одном или более объектах ValidationMessage. Затем контейнер, в свою очередь, может использовать эти значения для предоставления более точной информации о местонахождении ошибки.


Детали Проверки


Более детально, проверка выполняется так:


Во-первых, JSP-страница разбирается с использованием информации в TLD. На этом этапе проверяются атрибуты - мандатные и по выбору/optional.


Во-вторых, для всех директив taglib страницы, в лексическом порядке их появления, вызывается класс их ассоциированного проверщика (если имеется). Это вызывает выполнение нескольких дополнительных шагов.

Первый шаг выполняется для получения инициализированного экземпляра проверщика путём, либо:

Имя класса - такое, какое указано в элементе <validator-class>, а Map, переданный в setInitParameters() - такой, как описано в элементе <init-params>. Предполагается, что все классы TagLibraryValidator сохраняют свои initParameters до тех пор, пока не будут установлены новые или пока release() не будет в них вызван.


Второй дополнительный шаг выполняет реальную проверку. Это делается через вызов метода validate() с префиксом, uri и PageData, которые соответствуют проверяемому экземпляру директивы taglib и PageData, представляющему эту страницу.


Последний дополнительный шаг вызывает метод release() в тэге проверщика, когда он уже больше не нужен.

Этот метод освобождает все ресурсы.


Наконец, после проверки всех классов проверщика библиотеки тэгов, классы TagExtraInfo для всех тэгов будут проверяться вызовом их метода isValid. Порядок вызова этого метода не определён.

JSP.10.5.1 TagLibraryInfo


Синтаксис


public abstract class TagLibraryInfo


Описание


Это информация времени трансляции, ассоциированная с директивой taglib и её TLD-файлом. Большая часть информации получается непосредственно из TLD, за исключением значений префикса и uri, используемых в директиве taglib.

JSP.10.5.1.16 Поля


protected java.lang.String info

protected java.lang.String jspversion

protected java.lang.String prefix

protected java.lang.String shortname

protected TagInfo[] tags

protected java.lang.String tlibversion

protected java.lang.String uri

protected java.lang.String urn


JSP.10.5.1.17 Конструкторы


protected TagLibraryInfo(java.lang.String prefix, java.lang.String uri)


Конструктор. Будут вызываться конструкторы для TagInfo и TagAttributeInfo после разбора TLD-файла.


Параметры:


prefix
- префикс, используемый директивой taglib

uri - URI, используемый директивой taglib

JSP.10.5.1.18 Методы


public java.lang.String getInfoString()

  Информация (документация) для данного TLD.


public java.lang.String getPrefixString()

  Префикс, назначенный этой taglib из директивы <%taglib.


public java.lang.String getReliableURN()

  "Надёжное" URN, указанное в TLD. Может использоваться утилитами авторизации в качестве глобального идентификатора (атрибут uri) при создании директивы taglib для данной библиотеки.


public java.lang.String getRequiredVersion()

  Строка, описывающая требуемую версию JSP-контейнера.


public java.lang.String getShortName()

  Предпочтительное краткое имя (префикс), как указано в TLD. Может использоваться утилитами авторизации в качестве предпочтительного префикса при создании директивы include для данной библиотеки.


public TagInfo getTag(java.lang.String shortname)

  Получает TagInfo для данного имени тэга, просматривая все тэги в данной библиотеке тэгов.


Параметры:


shortname
- Краткое имя (не префикс) тэга.


public TagInfo[] getTags()
  Массив, описывающий тэги, определённые в данной библиотеке.


public java.lang.String getURI()

  Значение атрибута uri из директивы <%@ taglib для данной библиотеки.

JSP.10.5.2 TagInfo


Синтаксис

public class TagInfo


Описание


Информация Tag для тэга в Библиотеке Тэгов; этот класс инстанциируется из файла TLD/Дескриптора Библиотеки Тэгов и доступна только во время трансляции.

JSP.10.5.2.19 Поля
 

public static final java.lang.String BODY_CONTENT_EMPTY
 static-константа для getBodyContent(), если он пустой.


public static final java.lang.String BODY_CONTENT_JSP

 static-константа для getBodyContent(), если это JSP.


public static final java.lang.String BODY_CONTENT_TAG_DEPENDENT

 static-константа для getBodyContent(), если это зависит от Tag.


JSP.10.5.2.20 Конструкторы


public TagInfo(java.lang.String tagName, java.lang.String tagClassName, java.lang.String bodycontent, java.lang.String infoString, TagLibraryInfo taglib, TagExtraInfo tagExtraInfo, TagAttributeInfo[] attributeInfo)


Конструктор для TagInfo из данных в формате JSP 1.1 для TLD. Этот класс инстанциируется только из кода TagLibrary по запросу из некоторого кода JSP, разбирающего TLD (Tag Library Descriptor). Заметьте, что, поскольку TagLibibraryInfo отражает информацию TLD и директивы taglib, экземпляр TagInfo зависит от директивы taglib. Возможно это ошибка дизайна, которая может быть зафиксирована в будущем.


Параметры:


tagName
- имя того тэга.

tagClassName - имя класса обработчика тэга.

bodycontent - информация о теле содержимого этих тэгов.

infoString - строковая информация (optional) для данного тэга.

taglib - экземпляр библиотеки тэгов, содержащей их.

tagExtraInfo - экземпляр, предоставляющий дополнительную информацию о тэге. Может быть null.

attributeInfo - массив данных AttributeInfo из дескриптора. Может быть null.


public TagInfo(java.lang.String tagName, java.lang.String tagClassName, java.lang.String bodycontent, java.lang.String infoString, TagLibraryInfo taglib, TagExtraInfo tagExtraInfo, TagAttributeInfo[] attributeInfo, java.lang.String displayName, java.lang.String smallIcon, java.lang.String largeIcon, TagVariableInfo[] tvi)


Конструктор для TagInfo из данных в формате JSP 1.2 для TLD. Этот класс инстанциируется только из кода TagLibrary по запросу из некоторого кода JSP, разбирающего TLD. Заметьте, что, поскольку TagLibibraryInfo отражает информацию TLD и директивы taglib, экземпляр TagInfo зависит от директивы taglib. Возможно это ошибка дизайна, которая может быть зафиксирована в будущем.


Параметры:


tagName
- имя того тэга.

tagClassName - имя класса обработчика тэга.

bodycontent - информация о теле содержимого этих тэгов.

infoString - строковая информация (optional) для данного тэга.

taglib - экземпляр библиотеки тэгов, содержащей их.

tagExtraInfo - экземпляр, предоставляющий дополнительную информацию о тэге. Может быть null.

attributeInfo - массив данных AttributeInfo из дескриптора. Может быть null.

displayName - краткое имя для отображения утилитами.

smallIcon - путь к маленькой иконке, отображаемой утилитами.

largeIcon - путь к большой иконке, отображаемой утилитами.

tagVariableInfo - массив TagVariableInfo (или null).


JSP.10.5.2.21 Методы


public TagAttributeInfo[] getAttributes()


Информация атрибута (в TLD) в этом тэге. Возвращается массив, описывающий атрибуты данного тэга, как указано в TLD. Возврат null означает отсутствие атрибутов.


Возвращает: массив TagAttributeInfo для данного тэга.


public java.lang.String getBodyContent()


Информация bodycontent для данного тэга.


Возвращает: строку содержимого тела.


public java.lang.String getDisplayName()


Получает displayName.


Возвращает: Краткое имя для вывода утилитами.


public java.lang.String getInfoString()


Информационная строка для тэга.


Возвращает: информационную строку.


public java.lang.String getLargeIcon()


Получает путь к большой иконке.


Возвращает: путь к большой иконке, отображаемой утилитами.


public java.lang.String getSmallIcon()


Получает путь к маленькой иконке.


Возвращает: путь к маленькой иконке, отображаемой утилитами.


public java.lang.String getTagClassName()


Имя класса, предоставляющего обработчик для данного тэга.


Возвращает: имя класса обработчика тэга.


public TagExtraInfo getTagExtraInfo()


Экземпляр (если имеется) для дополнительной информации тэга.


Возвращает: экземпляр TagExtraInfo, если имеется.


public TagLibraryInfo getTagLibrary()


Экземпляр TagLibraryInfo, к которому мы принадлежим.


Возвращает: экземпляр библиотеки тэгов, к которому мы принадлежим.


public java.lang.String getTagName()


Имя тэга.


Возвращает: (краткое) имя тэга.


public TagVariableInfo[] getTagVariableInfos()


Получает объекты TagVariableInfo, ассоциированные с этим TagInfo.


Возвращает: объект TagVariableInfo, ассоциированный с этим объектом.


public VariableInfo[] getVariableInfo(TagData data)


Информация об объектах скриптинга, созданных этим тэгом на этапе прогона/runtime. Это удобный метод в ассоциированном классе TagExtraInfo. По умолчанию null, если тэг не имеет атрибута "id", иначе - {"id", Object}


Параметры:


data
- TagData, описывающие данную акцию.


Возвращает: массив элементов VariableInfo.


public booleanisValid(TagData data)


Проверка атрибутов на этапе трансляции. Это удобный метод в ассоциированном классе TagExtraInfo.


Параметры:


data
- экземпляр TagData времени трансляции.


Возвращает: верны ли данные.


public void setTagExtraInfo(TagExtraInfo tei)


Набор экземпляров для дополнительной информации тэга.


Параметры:


tei - экземпляр TagExtraInfo.


public void setTagLibrary(TagLibraryInfo tl)


Устанавливает свойство TagLibraryInfo. Заметьте, что элемент TagLibraryInfo зависит не просто от информации TLD, но также и от специфики используемого экземпляра taglib. Это означает, что некоторая работа должна быть проделана для конструирования и инициализации объектов TagLib. Если использовать аккуратно, этот setter поможет исключить необходимость создания новых элементов TagInfo для каждой директивы taglib.


Параметры:


tl
- назначаемый TagLibraryInfo.


public java.lang.String toString()


Строго для целей отладки ...


Переопределяет: java.lang.Object.toString() в классе java.lang.Object

JSP.10.5.3 TagAttributeInfo


Синтаксис
 

public class TagAttributeInfo


Описание


Информация об атрибуте тэга, доступная во время трансляции. Этот класс инстанциируется из файла TLD. Сюда включается только информация, необходимая для генерации кода. Друга информация типа SCHEMA для проверки выводится в других местах.

JSP.10.5.3.22 Поля
 

public static final java.lang.String ID


"id"
окружается, чтобы стать ID. Реально это не даёт преимущества, поскольку IDREF не обрабатываются раздельно.

JSP.10.5.3.23 Конструкторы


public TagAttributeInfo(java.lang.String name, boolean required, java.lang.String type, boolean reqTime)


Конструктор для TagAttributeInfo. Этот класс инстанциируется только из кода TagLibrary по запросу из некоторого JSP-кода, разбирающего TLD.


Параметры:


name
- имя атрибута.

required - необходим ли атрибут в экземплярах тэга.

type - имя типа атрибута.

reqTime - содержит ли данный атрибут Attribute времени запроса.


JSP.10.5.3.24 Методы


public booleancanBeRequestTime()


Может ли данный атрибут содержать значение времени запроса.


Возвращает: может ли данный атрибут содержать значение времени запроса.


public static TagAttributeInfo getIdAttribute(TagAttributeInfo[] a)


Удобный static-метод, проходящий по массиву объектов TagAttributeInfo и ищущий "id".


Параметры:


a - массив TagAttributeInfo.


Возвращает: ссылку на TagAttributeInfo с именем "id".


public java.lang.String getName()


Имя этого атрибута.


Возвращает: имя атрибута.


public java.lang.String getTypeName()


Тип (как String) этого атрибута.


Возвращает: тип атрибута.


public booleanisRequired()


Необходим ли данный атрибут.


Возвращает: необходим ли данный атрибут.


public java.lang.String toString()


Переопределяет: java.lang.Object.toString() в классе java.lang.Object

JSP.10.5.4 PageData


Синтаксис


public abstract class PageData


Описание


Информация времени трансляции о JSP-странице. Информация соответствует XML-просмотру JSP-страницы.

Объекты этого типа генерируются JSP-транслятором, например, при передаче экземпляру TagLibraryValidator.

JSP.10.5.4.25 Конструкторы


public PageData()

JSP.10.5.4.26 Методы
 

public abstract java.io.InputStream getInputStream()

Возвращает поток ввода в XML-просмотре JSP-страницы. Вызывает XML-просмотр JSP-страницы, который содержит развёрнутые директивы include.


Возвращает: поток ввода документа.

JSP.10.5.5 TagLibraryValidator


Синтаксис


public abstract class TagLibraryValidator


Описание


Класс проверщика этапа трансляции для JSP-страницы. Проверщик оперирует документом XML, ассоциированным с JSP-страницей. TLD-файл ассоциирует класс TagLibraryValidator и некоторые init-аргументы с библиотекой тэгов.

JSP-контейнер отвечает за размещение соответствующих объектов соответствующего подкласса через:

Экземпляр TagLibraryValidator может создавать вспомогательные объекты внутри для выполнения проверки (например, проверщик XSchema) и может использовать их для всех страниц в ходе данной трансляции.

JSP-контейнер не сериализует гарантированно вызовы метода validate(), и TagLibraryValidator'ы должны выполнять синхронизацию, которая может потребоваться.


JSP-контейнер может по выбору поддерживать атрибут jsp:id для предоставления качественной проверки ошибок. Если такая поддержка имеется, контейнер будет отслеживать JSP-страницы, передаваемые контейнеру, и будет назначать каждому элементу уникальный "id", который передаётся как значение атрибута jsp:id. Каждый элемент XML, доступный в XML-просмотре, будет расширен этим атрибутом.

TagLibraryValidator
может затем использовать этот атрибут в одном или более объектах ValidationMessage. Контейнер тогда, в свою очередь, может использовать эти значения для предоставления более точной информации о местонахождении ошибки.

JSP.10.5.5.27 Конструкторы
 

public TagLibraryValidator()

JSP.10.5.5.28 Методы


public java.util.Map getInitParameters()


Получает данные init-параметров как неизменяемую Map/Карту. Имена параметров это ключи, а значения параметров - это значения.


Возвращает: параметры init как неизменяемую карту.


public void release()


Высвобождает любые данные, хранимые этим экземпляром, с целью проверки.


public void setInitParameters(java.util.Map map
)

Устанавливает данные init в TLD для этого проверщика. Имена параметров это ключи, а значения параметров - это значения.


Параметры:


initMap
- карта, описывающая параметры init.


public ValidationMessage[] validate(java.lang.String prefix, java.lang.String uri, PageData page)


Проверяет JSP-страницу. Будет вызван однократно на каждую директиву в JSP-странице. Этот метод возвратит null, если страница верна/valid; иначе метод должен возвратить массив объектов ValidationMessage. Массив нулевой длины также интерпретируется как отсутствие ошибок.


Параметры:


prefix
- значение аргумента prefix в директиве.

uri - значение аргумента uri в директиве.

thePage - JspData-объект страницы.

Возвращает: null-объект, или массив нулевой длины при отсутствии ошибок, или массив объектов ValidationMessages.

JSP.10.5.6 ValidationMessage


Синтаксис


public class ValidationMessage


Описание


Сообщение о проверке из TagLibraryValidator. JSP-может (по выбору) поддерживать атрибут jsp:id для предоставления качественной проверки ошибок. Если такая поддержка имеется, контейнер будет отслеживать JSP-страницы, передаваемые контейнеру, и будет назначать каждому элементу уникальный "id", который передаётся как значение атрибута jsp:id. Каждый элемент XML, доступный в XML-просмотре, будет расширен этим атрибутом. TagLibraryValidator может затем использовать этот атрибут в одном или более объектах ValidationMessage. Контейнер тогда, в свою очередь, может использовать эти значения для предоставления более точной информации о местонахождении ошибки.

JSP.10.5.6.29 Конструкторы


public ValidationMessage(java.lang.String id, java.lang.String message)


Создаёт ValidationMessage. String сообщения должна быть не-null. Значение id может быть null, если сообщение не специфично для XML-элемента или если не были переданы никакие атрибуты jsp:id. Если не-null, значение id обязано быть значением атрибута jsp:id для PageData, передаваемым в метод validate().


Параметры:


id
- либо null, либо значение атрибута jsp:id.

message - локализованное сообщение о проверке.

JSP.10.5.6.30 Методы
 

public java.lang.String getId()

Получает jsp:id.
null означает, что нет доступной информации.


Возвращает: jsp:id-информацию.


public java.lang.String getMessage()


Получает локализованное сообщение о проверке.


Возвращает: сообщение о проверке.

JSP.10.5.7 TagExtraInfo


Синтаксис


public abstract class TagExtraInfo


Описание


Класс по выбору, предоставляемый автором библиотеки тэгов для описания дополнительной информации времени трансляции, не указанной в TLD. Класс TagExtraInfo упоминается в файле TLD.

Этот класс может использоваться:

JSP-транслятор отвечает за то, чтобы начальное значение, возвращаемое в вызове getTagInfo(), соответствовало объекту TagInfo транслируемого тэга. Если выполняется явный вызов setTagInfo(), тогда передаваемый объект будет возвращён в последующих вызовах getTagInfo().

Единственный способ повлиять на значение, возвращаемое методом getTagInfo(), - через вызов setTag-Info() и, следовательно, TagExtraInfo.setTagInfo() вызывается JSP-транслятором с объектом TagInfo, который соответствует транслируемому тэгу. Это должно происходить до любого вызова isValid()  и до любого вызова getVariableInfo().

JSP.10.5.7.31 Конструкторы

public TagExtraInfo()

JSP.10.5.7.32 Методы

public final TagInfo getTagInfo()

Получает TagInfo для этого класса.


Возвращает: экземпляр taginfo, расширяемый данным экземпляром.


public VariableInfo[] getVariableInfo(TagData data)


Информация о переменных скриптинга, определённых тэгом, ассоциированным с данным экземпляром TagExtraInfo. Атрибуты времени запроса указаны как таковые в параметре TagData.


Параметры:


data
- экземпляр TagData.


Возвращает: массив данных VariableInfo.


public boolean isValid(TagData data)


Проверка атрибутов на этапе трансляции. Атрибуты времени запроса указаны как таковые в параметре TagData.


Параметры:


data
- экземпляр TagData.


Возвращает: верен ли этот экземпляр тэга.


public final void setTagInfo(TagInfo tagInfo)


Устанавливает TagInfo для данного класса.


Параметры:


tagInfo
- TagInfo, расширяемая этим экземпляром.

JSP.10.5.8 TagData


Синтаксис


public class TagData implements java.lang.Cloneable


Все Реализованные Интерфейсы: java.lang.Cloneable


Описание


Информация (только времени трансляции) атрибута/значения для экземпляра тэга. TagData используется только в качестве аргумента методов isValid и getVariableInfo в TagExtraInfo, которые вызываются во время трансляции.

JSP.10.5.8.33 Поля


public static final java.lang.Object REQUEST_TIME_VALUE


Значение, отличное от атрибута, для указания, что его (атрибута) значение является выражением времени запроса (которое ещё не доступно, поскольку экземпляры TagData используются на этапе трансляции).

JSP.10.5.8.34 Конструкторы


public TagData(java.util.Hashtable attrs)


Конструктор для TagData. Если Вы уже имеете атрибуты в хэш-таблице, используйте этот конструктор.


Параметры:


attrs
- хэш-таблица для получения из неё значений.


public TagData(java.lang.Object[][] atts)


Конструктор для TagData.


Типичный конструктор может быть таким:


static final Object[][] att = {{"connection", "conn0"},

{"id", "query0"}};

static final TagData td = new TagData(att);


Значения обязаны быть String, за исключением тех, которые содержат известные объекты REQUEST_TIME_VALUE.


Параметры: atts - статические атрибут и значения. Может быть null.

JSP.10.5.8.35 Методы


public java.lang.Object getAttribute(java.lang.String attName)


Значение атрибута. Содержит известный объект REQUEST_TIME_VALUE, если значение является значением этапа запроса. Возвращает null, если атрибут не установлен.


Возвращает: объект значения атрибута.


public java.util.Enumeration getAttributes()


Перечисляет атрибуты.


Возвращает: перечисление атрибутов в TagData.


public java.lang.String getAttributeString(java.lang.String attName)


Получает значение для данного атрибута.


Возвращает: строка значений атрибута.


public java.lang.String getId()


Значение атрибута id, если имеется.


Возвращает: значение атрибута id или null.


public void setAttribute(java.lang.String attName, java.lang.Object value)


Устанавливает значение атрибута.


Параметры:


attName
- имя атрибута.

value - значение.

JSP.10.5.9 VariableInfo


Синтаксис


public class VariableInfo


Описание


Информация о переменных скриптинга, которые создаются/модифицируются тэгом (на этапе прогона). Эта информация предоставляется классами TagExtraInfo и используется фазой трансляции JSP.

Переменные скриптинга, генерируемые специальной акцией, могут иметь значения области видимости page, request, session и application.

Имя класса (VariableInfo.getClassName) в возвращаемых объектах может использоваться для определения типов переменных скриптинга. В связи с этим специальная акция не может создавать переменную скриптинга примитивного/базового типа. Чтобы обойти это, используйте "boxed/боксовые" типы.

Имя класса может быть Полным Квалифицированным Именем Класса, или кратким именем класса.

Если предоставляется Полное Квалифицированное Имя Класса, оно должно ссылаться на класс, находящийся в CLASSPATH для Web-Приложения (см. спецификацию Servlet 2.3 - как правило это WEB-INF/lib и WEB-INF/classes). Невыполнение этого приводит к ошибке времени трансляции.

Если дано краткое имя класса в объектах VariableInfo, тогда имя класса обязано быть именем public-класса в контексте директив import страницы, на которой специальная акция появилась (будет проверяться, имеется ли словоблудие JLS для ссылки на него). Класс обязан также быть в CLASSPATH для Web-Приложения (см. спецификацию Servlet 2.3 - как правило это WEB-INF/lib и WEB-INF/classes). Невыполнение этого приводит к ошибке времени трансляции.

Использование Комментариев

Часто полное квалифицированное имя класса ссылается на класс, который известен библиотеке тэгов и, следовательно, находится в том же JAR-файле, что и обработчики тэгов. В большинстве других случаев оно ссылается на класс, который находится на платформе, на которой построен JSP-процессор (типа J2EE).

Употребление полных квалифицированных имён в такой манере делает их использование относительно устойчивым к ошибкам конфигурации.

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


Протокол Синхронизации

Результатом вызова getVariableInfo является массив объектов VariableInfo. Каждый такой объект описывает переменную скриптинга, предоставляя её имя, тип, указывая, является ли переменная новой или нет, и какова её область видимости. Область видимости лучше видна на рисунке:
 


Спецификация JSP 1.2 определяет интерпретацию трёх значений:

Значение области видимости переменной предполагает, какие методы влияют на значение и, следовательно, где нужна синхронизация:

Информация о Переменной в TLD

Информация переменной скриптинга может быть также непосредственно кодирована для большинства случаев в Tag Library Descriptor путём использования субэлемента <variable> элемента <tag>. См. спецификацию JSP.

JSP.10.5.9.36 Поля

public static final int AT_BEGIN
  Информация области видимости о том, что переменная скриптинга видна после начального тэга.


public static final int AT_END

  Информация области видимости о том, что переменная скриптинга видна после конечного тэга.


public static final int NESTED

  Информация области видимости о том, что переменная скриптинга видна только между начальным/конечным тэгами.


JSP.10.5.9.37 Конструкторы


public VariableInfo(java.lang.String varName, java.lang.String className, boolean declare, int scope)


Конструктор. Эти объекты могут быть созданы (на этапе трансляции) экземплярами TagExtraInfo.


Параметры:


id
- имя переменной скриптинга.

className - имя переменной скриптинга (наверное, класса??).

declare - если true, это новая переменная (в некоторых языках это требует объявления).

scope - обозначение лексической области видимости переменной.

JSP.10.5.9.38 Методы


public java.lang.String getClassName()

public boolean getDeclare()

public int getScope()

public java.lang.String getVarName()

JSP.10.5.10 TagVariableInfo


Синтаксис


public class TagVariableInfo


Описание


Информация переменной для тэга в Библиотеке Тэгов. Этот класс инстанциируется из TLD-файла и доступен только во время трансляции. Этот объект должен быть неизменяемым.

Данная информация доступна только в формате JSP 1.2.

JSP.10.5.10.39 Конструкторы


public TagVariableInfo(java.lang.String nameGiven, java.lang.String nameFromAttribute, java.lang.String className, boolean declare, int scope)


Конструктор для TagVariableInfo.


Параметры:


nameGiven
- значение <name-given>

nameFromAttribute - значение <name-from-attribute>

className - значение <variable-class>

declare - значение <declare>

scope - значение <scope>

JSP.10.5.10.40 Методы


public java.lang.String getClassName()

Тело элемента <variable-class>.


Возвращает: имя класса переменной.


public booleangetDeclare()


Тело элемента <declare>.


Возвращает: объявляется переменная, или нет.


public java.lang.String getNameFromAttribute()


Тело элемента <name-from-attribute>. Это имя атрибута, чьё значение (этапа трансляции) даст имя переменной. Необходимо одно из: <name-given> или <name-from-attribute>.


Возвращает: атрибут, чьё значение определяет имя переменной.


public java.lang.String getNameGiven()


Тело элемента <name-given>.


Возвращает: имя переменной как константу.


public int getScope()


Тело элемента <scope>.


Возвращает: область видимости для переменной.