Читать «Java 7 (Наиболее полное руководство)» онлайн - страница 440

Ильдар Шаукатович Хабибуллин

</tag>

<tag>

<name>insert</name>

<tag-class>sdotags.InsertTag</tag-class>

</tag>

Для связи обработчиков тегов используются их методы. Сначала обработчик вложенного тега задает себе внешний, "родительский" тег parent методом

public void setParent(Tag parent);

Затем обработчик вложенного тега может обратиться к обработчику внешнего тега методом

public Tag getParent();

Более общий метод

public static final Tag findAncestorWithClass(Tag from, Class class);

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

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

Допустим, класс ConnectionTag, реализующий пользовательский тег connection, устанавливает соединение с источником данных, как показано в листинге 27.9.

Листинг 27.9. Реализация тега соединения с базой данных

public class ConnectionTag extends TagSupport{

private Connection conn;

public Connection getConnection(){ return conn;

}

public int doStartTag(){

Connection conn = DriverManager.getConnection(url, user, password);

if (conn == null) return SKIP_BODY; return EVAL_BODY_INCLUDE;

}

public int doEndTag(){ conn = null; return EVAL_BODY;

}

}

Класс QueryTag, реализующий тег query, может воспользоваться объектом conn, как показано в листинге 27.10.

Листинг 27.10. Реализация связанного тега

public class QueryTag extends BodyTagSupport{

private ConnectionTag parent;

public int doStartTag(){

parent = (ConnectionTag)findAncestorWithClass(this, ConnectionTag.class);

if (parent == null) return SKIP BODY; return EVAL_BODY_INCLUDE;

}

public int doAfterBody(){

Connection conn = parent.getConnection();

// Прочие действия

return SKIP_BODY;

}

}

Другой способ сделать объект obj доступным для нескольких тегов — указать его в виде атрибута какого-нибудь контекста. Это выполняется методом

public void setAttribute(String name, Object obj);

класса PageContext. Контекст этого атрибута — страница, на которой он определен. Если область действия атрибута надо расширить, то используется метод

public void setAttribute(String name, Object obj, int scope);

того же класса. Третий аргумент данного метода задает область действия атрибута — это одна из констант: page_scope, application_scope, request_scope, session_scope.

Значение атрибута всегда можно получить методами

public Object getAttribute(String name, int scope); public Object getAttribute(String name);

класса PageContext.

Для удобства работы с атрибутом обработчик тега может создать переменную, известную в области действия атрибута и доступную для других тегов в этой области (scripting variable). Она будет содержать ссылку на созданный атрибут. Переменную можно определить не только по атрибуту контекста, но и по атрибуту открывающего тега. Для определения переменной есть два способа.

Первый способ — указать в TLD-файле элемент <variable>, описывающий переменную. В этот элемент вкладывается хотя бы один из двух элементов: