понедельник, 9 января 2012 г.

Пишем расширение для Mylyn. Основа расширения

   Итак, мы настроили окружение для разработки на базе Mylyn framework и теперь можно приступать непосредственно к созданию скелета нового плагина. Я рассчитываю что у вас уже есть базовое понимание внутренней архитектуры Eclipse и использования OSGI. Для ознакомления с основами рекомендую почитать заметки Павла Смолысова о Equinox.

   В рамках этого цикла статей мы напишем коннектор к выдуманной Bug Management System (BMS): TTrac. Это позволит нам сконцентрироваться на реализации плагина, а не реализации конкретных особенностей протокола BMS. За основу мы возьмем коннектор org.eclipse.mylyn.trac, который входит в состав Mylyn и обеспечивает интеграцию с популярной системой управления проектами Trac


1. Создание проектов

   Нам необходимо создать 3 проекта:
  • Plugin: ru.jdevel.mylyn.ttrac.core (Содержит код интеграции с TTraс)
    • Project Type: Plugin
    • Project name: ru.jdevel.mylyn.ttrac.core
    • ID: ru.jdevel.mylyn.ttrac.core
    • Name: Mylyn TTrac Connector Core
    • Provider: jdevel.ru
    • Activator: ru.jdevel.mylyn.ttrac.core.TTracCorePlugin
  • Plugin: ru.jdevel.mylyn.ttrac.ui (Содержит код UI компонентов, которые будут интегрированы в Eclipse)
    • Project Type: Plugin
    • Project name: ru.jdevel.mylyn.ttrac.ui
    • ID: ru.jdevel.mylyn.ttrac.ui
    • Name: Mylyn TTrac Connector UI
    • Provider: jdevel.ru 
    • Activator: ru.jdevel.mylyn.ttrac.core.TTracUIPlugin
  • Feature: ru.jdevel.mylyn.ttrac-feature
    • Project Type:Feature
    • Project name: ru.jdevel.mylyn.ttrac-feature
    • ID: ru.jdevel.mylyn.ttrac_feature
    • Name: Mylyn Tasks Connector: TTrac
    • Provider: jdevel.ru 
    Создание Feature Project ttrac-feature
    • Содержит мета-информацию о нашем коннекторе
    • Должен включать в себя 2 ранее созданных плагина ttrac.core и ttrac.ui
    Следующим этапом будет интеграция нашего коннектора в Eclipse. Здесь нам очень поможет исходный код коннектора для Trac. Если мы сейчас запустим Eclipse с окружением из ткущего workspace, то увидим в списке установленных плагинов наши:
Список активных plug-ins
2. Реализация расширений (extension)

    Наши плагины загружены, но ничего не умеют делать. Давайте добавим наш плагин в список известных коннекторов Mylyn. В проекте ru.jdevel.mylyn.ttrac.ui открываем MANIFEST.MF и переходим на вкладку Extensions. В качестве фильтра задаем mylyn и снимаем галочку с пункта: Show only extension points from the reuired plug-ins
Мы хотим расширить org.eclipse.mylyn.tasks.ui.repositories
Меню выбора точки расширения
  В результате будет создано расширение для сущности Repository и в зависимости нашего плагина будет добавлен: org.eclipse.mylyn.tasks.ui. По умолчанию для этой точки расширения будет создан класс AbstractRepositoryConnector1, переименуем его в TtracRepositoryConnector. Теперь необходимо написать реализацию этого класса, он должен быть наследником AbstractRepositoryConnector, а для этого в зависимости нашего плагина надо добавить org.eclipse.mylyn.tasks.core.
  Если теперь запустить Eclipse, то в диалоге добавления нового репозитария Mylyn мы увидим наш безымянный коннектор:
Список доступных коннекторов Mylyn





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

3. Реализация TtracRepositoryConnector

Класс TtracRepositoryConnector является первой точкой интеграции нашего плагина и Eclipse. Рекомендую вам ознакомиться с классом AbstractRepositoryConnector чтобы понять назначение его методов. Сами методы AbstractRepositoryConnector можно разделить на пять групп:

- проверка поддержки фичи:
 public boolean canCreateNewTask(TaskRepository repository)
 public boolean canCreateTaskFromKey(TaskRepository repository)
В качестве реализации можно смело оставлять return false;

- получение типа соединения/имени репозитария:
 public String getConnectorKind()
 public String getLabel()
    В качестве реализации будем возвращать REST и Ttrac Sample repository

- работа с URL репозитрия/задач:
 public String getRepositoryUrlFromTaskUrl(String taskFullUrl)
 public String getTaskIdFromTaskUrl(String taskFullUrl)
 public String getTaskUrl(String repositoryUrl, String taskId)

    В качестве реализации можем возвращать repositoryUrl

- работа с задачами:
 public void updateTaskFromTaskData(TaskRepository taskRepository,
   ITask task, TaskData taskData)
        - оставляем пустую реализацию

 public boolean hasTaskChanged(TaskRepository taskRepository, ITask task,
   TaskData taskData)
        - возвращаем false

- выполнение операций с репозитарием (основные методы):
 public TaskData getTaskData(TaskRepository taskRepository, String taskId,
   IProgressMonitor monitor)
 public IStatus performQuery(TaskRepository repository,
   IRepositoryQuery query, TaskDataCollector collector,
   ISynchronizationSession session, IProgressMonitor monitor)

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

 @Override
 public TaskData getTaskData(TaskRepository taskRepository, String taskId,
   IProgressMonitor monitor) throws CoreException {
  TaskData task = new TaskData(new TaskAttributeMapper(taskRepository), TTRAC_CONNECTOR_KIND, taskRepository.getRepositoryUrl(), taskId);
  
  return task;
 }

 @Override
 public IStatus performQuery(TaskRepository repository,
   IRepositoryQuery query, TaskDataCollector collector,
   ISynchronizationSession session, IProgressMonitor monitor) {
  return Status.OK_STATUS;
 }
Если теперь запустить Eclipse, то мы увидим что наш коннектор уже не безымянный:
Наш коннектор в списке доступных
но все еще не работает. Если выбрать наш коннектор и попробовать нажать Next, мы увидим в консоли Eclipse:
!ENTRY org.eclipse.ui 4 0 2012-01-09 22:29:33.965
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.NullPointerException
 at org.eclipse.mylyn.internal.tasks.ui.wizards.NewRepositoryWizard.updateSettingsPage(NewRepositoryWizard.java:118)
 
4. Реализация TtracRepositoryConnector
    Оказывается нам надо не только реализовать AbstractRepositoryConnector, но и необязательный AbstractRepositoryConnectorUi:
Расширение ConnectorUI
    Этот класс отвечает за реализацию мастера подключения нового репозитария. В нем реализуется задание основных настроек репозитария.
Его основные методы:
 public String getConnectorKind() - аналог метода в TtracRepositoryConnector
 public ITaskRepositoryPage getSettingsPage(TaskRepository taskRepository) - возращает окно с настройками репозитария,
  необходимо создать класс public class TtracRepositorySettingsPage extends AbstractRepositorySettingsPage 
 
часть методов заменим шаблонной реализацией:
 @Override
 public IWizard getQueryWizard(TaskRepository taskRepository,
   IRepositoryQuery queryToEdit) {
  RepositoryQueryWizard wizard = new RepositoryQueryWizard(taskRepository);
  return wizard;
 }

 @Override
 public IWizard getNewTaskWizard(TaskRepository taskRepository,
   ITaskMapping selection) {
  return new NewTaskWizard(taskRepository, selection);
 }
После небольшой доработки вновь запускаем Eclipse и видим результат нашей работы:

Мастер настроек TTrac коннектора
5. Заключение
Мы реализовали простейший repository connector для Mylyn. На текущем этапе его возможностей достаточно только для добавления репозитария задач в Mylyn, но далее мы научим его многим интересным вещам:
  • извлечение задач из репозитария
  • отображение задач в Eclipse 
Исходный код этой статьи доступен в mercurial репозитарии jdevel_mylyn_tutorial @ : bitbucket

Комментариев нет:

Отправить комментарий