Представим следующую ситуацию: вы разрабатываете GWT приложение и ваши сущности(domain entities - основные структурные строительные блоки любой системы) имеют поля в виде перечислений(Enum). Ваши Proxies/DTO также работают с полями в виде перечислений. Но когда данные приходят на клиентскую часть(UI), то виджет ListBox работает только со строковым(String) форматом и необходимо выполнить преобразования из enum в String, и наоборот из String в enum. Но было бы хорошо иметь такой виджет, который бы умел работать с enum как со строками. Также добавим виджету возможность связывания данных между бином и UI-полями. Это возможность доступна благодаря GWT Editor framework.
Для начала создадим список перечислений возможных значений статуса:
Создадим ListBox умеющий работать с перечислением как со строками. Для этого наследуем класс от ValueListBox, который реализует интрефейс IsEditor.
- public enum Status {
- PROGRESS,
- RESOLVED,
- REOPENED,
- CLOSED,
- OPEN;
- @Override
- public String toString() {
- return name().toLowerCase();
- }
- }
* This source code was highlighted with Source Code Highlighter.
Также нам необходимо создать классы EnumerationRenderer(отвечает за отрисовку объекта определенного типа в строковой форме) и EnumerationKeyProvider(обеспечивает ключ для элемента списка).
- public class EnumerationListBox<E extends Enum<E>> extends ValueListBox<E> {
- public EnumerationListBox() {
- super(new EnumerationRenderer<E>(), new EnumerationKeyProvider<E>());
- }
- public EnumerationListBox(Class<E> clazz) {
- this();
- setAcceptableValues(Arrays.asList(clazz.getEnumConstants()));
- }
- }
* This source code was highlighted with Source Code Highlighter.
- public class EnumerationRenderer<E extends Enum<E>> implements Renderer<E> {
- @Override
- public String render(E object) {
- return object == null ? "" : object.toString();
- }
- @Override
- public void render(E object, Appendable appendable) throws IOException {
- appendable.append(render(object));
- }
- }
* This source code was highlighted with Source Code Highlighter.
Теперь когда у нас есть enumeration список, создадим для него контейнер согласно Editor контракту.
- public class EnumerationKeyProvider<E extends Enum<E>> implements ProvidesKey<E> {
- @Override
- public Object getKey(E item) {
- return item == null ? null : item.name() ;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Добавим сюда механизм RequestFactory, который позволяет реализовать уровень доступа к данным на клиенте и сервере. Это позволяет структурировать серверный код в data-ориентированном виде и обеспечивает более высокий уровень абстракции чем GWT-RPC. Первоначально он был создан для CRUD операций на сущности, но позже добавили возможность использования как универсальный механизм RPC.
- public class TaskEditor extends Composite implements Editor<TaskProxy> {
- @UiField(provided = true)
- EnumerationListBox<Status> priority = new EnumerationListBox<Status>(Status.class);
- public TaskEditor() {
- initWidget(priority);
- priority.addValueChangeHandler(new ValueChangeHandler<Status>() {
- @Override
- public void onValueChange(ValueChangeEvent<Status> event) {
- // and you can do whatever you want with selected event.getValue()
- }
- });
- }
- }
* This source code was highlighted with Source Code Highlighter.
Создадим интерфейс TaskProxy для сущности Task и определим необходимые get/set методы. Все методы отображаются(mapped) по именованному соглашению, т.е. имена должны быть идентичными.
- @ProxyFor(value = Task.class)
- public interface TaskProxy extends EntityProxy {
- Status getPriority();
- public void setPriority(Status priority);
- }
* This source code was highlighted with Source Code Highlighter.
Создание полного client/server-примера, где будут разные Entity, DAO, Proxy, Locator, RequestFactory, RequestContext, Manager-class это уже дело отдельной статьи. А на этом все.
- public class Task {
- @NotNull private Status priority;
- public Status getPriority() {
- return priority;
- }
- public void setPriority(Status priority) {
- this.priority = priority;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Комментариев нет:
Отправить комментарий