В этой короткой заметке поведаю о простом, но полезном компоненте библиотеки primefaces и как он позволяет пользоваться enum'ами в xhtml, не испытывая стыда за написанный код.
Собственно, рассмотрим задачу, которая встала передо мной. Необходимо сделать tabview с несколькими вкладками. Это типовая задача и для реализации её на JSF просто нужно воспользоваться готовым компонентном. В библиотеке Primefaces для этого есть компонент tabView. Выглядит он примерно следующим образом:
<p:tabView orientation="left">
<p:tab title="Январь">
Не трещите, морозы,
В заповедном бору,
У сосны, у березы
Не грызите кору!
Полно вам воронье
Замораживать,
Человечье жилье
Выхолаживать!
</p:tab>
<p:tab title="Февраль">
Ветры, бури, ураганы,
Дуйте что есть мочи!
Вихри, вьюги и бураны,
Разыграйтесь к ночи!
В облаках трубите громко,
Вейтесь над землею.
Пусть бежит в полях поземка
Белою змеею!
</p:tab>
<p:tab title="Март">
Разбегайтесь, ручьи,
Растекайтесь, лужи,
Вылезайте, муравьи,
После зимней стужи!
Пробирается медведь
Сквозь лесной валежник.
Стали птицы песни петь,
И расцвел подснежник.
</p:tab>
</p:tabView>
Как видно для каждой вкладки задаётся свой заголовок и контент. Сразу же возникает желание вместо захардкоженных строчек в xhtml'ке создать enum и поместить возможные значение месяцев туда. Также благодаря тому, что в Java значения enum'ов могут иметь свои поля и методы, то возможно в дальнейшем расширить этот класс, задав для перечесления нужные значения полей, после чего иметь централизованное место для использования необходимых данных внутри отдельного tab'а.
Для примера выше получится следующим enum:
public enum Month {
JANUARY("Январь"),
FEBRUARY("Февраль"),
MARCH("Март"),
;
private final String title;
private Month(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
}
Внутри него же можно хранить текст стишка. После такой простой манипуляции встаёт вопрос: "А как теперь использовать enum в моей xhtml странице?".
Как известно для доступа к Java'овым объектам существует EL expressions, однако из него можно обращаться лишь к бинам. Просто так написав имя класса Month и обратиться к нужному значению не сработает.
Вообще в конкретно этом случае можно было создать bean и сделать в нём метод, который бы возвращал все возможные значения ENUM'а и использовать динамический tabView, но существуют варианты, когда нам это не подходит, так как не всегда содержимое можно сгенерировать общей стратегии для каждой из вкладок. Но как тогда поступить? Создавать в бине пачку полей для каждого из значений выглядит отвратительно и просто набивает код искуственными переменными.
Однако, в Primefaces для решения этой проблемы предусмотрен специальнйы компонент. В showcase он запрятан в раздел прочие, а так как потребность в таком возникает редко, но можно и недогадываться о его существовании. Поэтому приятно познакомиться, компонент importEnum.
Пользоваться им можно следующим образом :
<p:importEnum type="com.tuneit.model.Month" var="Month"/>
<p:tabView>
<p:tab title="${Month.JANUARY.title}>
Текст рыба
</p:tab>
<p:tab title="${Month.FEBRUARY.title}>
Текст рыба
</p:tab>
<p:tab title="${Month.MARCH.title}>
Текст рыба
</p:tab>
</p:tabView>
Как видно для того, чтобы пользоваться элементами перечисления необходимо лишь воспользоваться на странице компонентом для импорта.
На этом, пожалуй, откланяюсь.