 | Уровень сложности: средний Дэн Кен, ведущий инженер по программному обеспечению, IBM Лоренс Райт, студент, IBM
31.10.2007 Тот факт, что IBM Lotus Sametime функционирует поверх Lotus Expeditor, позволяет использовать Eclipse в качестве среды разработки плагинов (Plug-in Development Environment - PDE) для расширения функциональности Lotus Sametime множеством различных способов. В этой статье, второй части серии из четырёх частей, показан процесс разработки плагина BuddyNote с нуля.
Эта статья - вторая в серии из четырёх частей, посвящённой работе с плагинами в IBM Lotus Sametime V7.5.1. Из Части 1 "Работа с плагинами в IBM Lotus Sametime V7.5.1: настройка среды Eclipse" вы узнали, что Lotus Sametime V7.5.1 базируется на платформе расширенных клиентов IBM Lotus Expeditor, которая, в свою очередь, основана на модели плагинов Eclipse с открытым исходным кодом, и его можно настроить как среду разработки плагинов (Plug-in Development Environment, PDE) для Lotus Sametime. В Части 1 мы рассмотрели шаги по конфигурированию этой среды. В этом втором выпуске серии мы будем использовать рабочее пространство Eclipse, которое мы настроили в первой части, для разработки с нуля специального плагина, BuddyNote. Если вы не читали часть 1, можете загрузить и использовать рабочее пространство BuddyNote в разделе "Загрузка" данной статьи.
Примечание: чтобы использовать рабочее пространство BuddyNote, необходимо выполнить шаги из раздела "Install J9 Plug-In" первой части этой серии. Также необходимы IBM Lotus Sametime Connect V7.5.1 и IBM Lotus Sametime V7.5.1 SDK, установленные в папки по умолчанию (C:\Program Files\IBM\Sametime Connect и C:\st751sdk соответственно).
Эта серия статей предназначена для всех, кто интересуется расширением возможностей Lotus Sametime с помощью разработки плагинов. Вы должны быть знакомы с Lotus Sametime и уметь работать с ним.
Об этой серии
В этой серии из четырёх статей содержится введение в разработку плагинов Lotus Sametime V7.5.1 с помощью платформы Eclipse:
-
Часть 1 посвящена настройке Eclipse для разработки плагинов для Lotus Sametime V7.5.1.
- В этом выпуске, Части 2, мы с помощью Eclipse расширяем пользовательский интерфейс Lotus Sametime, создавая собственный плагин BuddyNote.
- В Части 3 показано, как отлаживать плагин с помощью входящих в состав Eclipse инструментов.
- В Части 4 показывается процесс развёртывания плагина, который позволяет вам поделиться вашим творением с другими, настроив проект Feature and Update Site.
Об этой статье
Целью данной статьи является введение в разработку плагинов Lotus Sametime V7.5.1 при помощи платформы Eclipse. Для этого мы шаг за шагом проведём разработку плагина BuddyNote. Плагин BuddyNote расширяет пользовательский интерфейс Lotus Sametime, добавляя так называемую область просмотра (view part), отображающую информацию в виде визитной карточки для лиц из Списка контактов и позволяющую пользователю добавлять текстовые записи. Эти записи хранятся локально и вызываются каждый раз, когда пользователь выбирает этот контакт. При первом подключении Lotus Sametime область просмотра BuddyNote отображает информацию о пользователе по умолчанию до тех пор, пока пользователь не выберет контакт, как показано на рисунке 1.
Рисунок 1. Завершённый плагин BuddyNote
В этой статье мы выполним следующие шаги для создания плагина BuddyNote и расширения пользовательского интерфейса Lotus Sametime:
- Задекларируем необходимые взаимозависимости
- Расширим точки расширения, необходимые для требуемой функциональности
- Создадим классы Java, обеспечивающие работу плагина
Если вы хотите заполнить все классы сразу, окончательный код можно найти в разделе "Загрузка". В частях 3 и 4 этой серии показано, как искать и устранять неисправности, а также развёртывать созданные вами собственные плагины.
Предварительные условия
Данная статья предназначена для специалистов, имеющих опыт Java-разработки, но не обязательно знакомых с разработкой в Eclipse или разработкой плагинов. У вас должен быть установлен Lotus Sametime V7.5.1, и вы должны уметь его использовать. Кроме того, необходим установленный Eclipse, а также чистое рабочее пространство, сконфигурированное для разработки плагинов Lotus Sametime V7.5.1. Инструкции по конфигурированию и системные требования см. в части 1 этой серии, "Настройка среды Eclipse", или загрузите и используйте рабочее пространство BuddyNote из раздела "Загрузка" этой статьи.
Введение
Перед тем как начать выполнять описанные в этой статье операции, мы рекомендуем закрыть все запущенные экземпляры Lotus Sametime.
Поскольку Lotus Sametime V7.5.1 базируется на платформе Eclipse, это приложение по существу представляет собой несколько взаимосвязанных компонентов-плагинов. Каждый компонент можно представить себе как пакет Java-классов, отвечающих за какую-то конкретную функциональность. Некоторые из этих пакетов расширяемы, что позволяет разрабатывать дополнительные плагины, расширяющие базовую функциональность. Для этого необходимо определить функциональность, которую расширяет плагин, а также задекларировать соответствующие плагины в качестве зависимостей. Это обеспечивает доступ к их точкам расширения и закладывают основу для разработки.
После того как определены точки расширения для необходимых зависимостей, нужно решить, в каком месте ваш плагин интегрируется с пользовательским интерфейсом. У каждой зависимости может быть множество точек расширения, в зависимости от функции, которой они управляют. Например, зависимость ChatWindow (com.ibm.collaboration.realtime.chatwindow) обеспечивает доступ к одной точке расширения для добавления к окну чата, а к другой - для создания всплывающего добавления. Необходимо идентифицировать надлежащую точку расширения, а также определить расширение. В Eclipse это несложно сделать при помощи шаблонов.
После идентификации точек расширения и определения расширений можно приступить к кодированию Java-классов, необходимых для выполнения новой функциональности. Eclipse предоставляет помощь, рекомендуя необходимые суперклассы и/или интерфейсы, требующиеся для некоторых расширений.
На примере плагина BuddyNote демонстрируется основная функциональность, необходимая при расширении пользовательского интерфейса Lotus Sametime, например выполнение следующих действий:
- Декларирование расширения для добавления приложения как области просмотра. Это область пользовательского интерфейса, в которой приложения, взаимодействующие с Lotus Sametime, могут отображаться с помощью сворачиваемых окон.
- Отслеживание перемещений человека.
- Локальное сохранение данных.
Кроме того, Lotus Sametime можно расширять, добавляя новые функции в виде кнопок на панели действий, всплывающих меню и пунктов меню инструментальной панели. Всё это не рассматривается в данной статье, однако, если это представляет для вас интерес, можете воспользоваться ссылками о расширении Lotus Sametime в разделе "Ресурсы".
Создание плагина
Чтобы сообщить Eclipse, что вы разрабатываете плагин, начнём с создания проекта плагина. Это действие обеспечивает доступ к среде разработки плагинов Eclipse и создаёт пакет, содержащий все необходимые плагину ресурсы.
- Выберите File - New - Project. Разверните Plug-in Development, выберите Plug-in Project и нажмите Next.
- Введите sample.buddynote в поле Project name. Все остальные опции примите по умолчанию.
- Нажмите Next.
- Введите удобное имя в поле Plug-in Name, либо сохраните предлагаемое по умолчанию имя Buddynote Plug-in. Все остальные опции примите по умолчанию.
- Нажмите Finish.
ПРИМЕЧАНИЕ: Может появиться вопрос - не желаете ли вы открыть перспективу Plug-In Development Perspective. Если да, нажмите Yes.
При выполнении вышеописанных операций проект sample.buddynote помещается в Package Explorer, а в центральном окне открывается Plug-In Overview, как показано на рисунке 2. Обратите внимание на вкладки в нижней части окна Overview, в особенности на вкладки Dependencies и Extensions.
Рисунок 2. Плагин BuddyNote - Overview
Добавление зависимостей плагина
Теперь, когда мы создали проект sample.buddynote необходимо задекларировать требуемые зависимости. Основываясь на его описании, плагин BuddyNote должен добавить к пользовательскому интерфейсу элемент application frame и обнаруживать событие выбора контактов. В таблице 1 перечислены некоторые зависимости плагинов, обеспечивающие доступ к точкам расширения для этих функций (для экономии места в таблице 1 * = com.ibm.realtime.collaboration).
Таблица 1. Зависимости плагина BuddyNote
| Плагин | Описание |
|---|
org.eclipse.core.runtime
org.eclipse.core.ui | Базовые плагины Eclipse; пользовательский интерфейс предоставляет точки расширения views для создания визуальных приложений |
|---|
| com.ibm.rcp.ui | Предоставляет точку расширения shelfViews для размещения области просмотра в приложении Lotus Sametime |
|---|
| *.community | Управляет различными IM-сообществами при помощи общего API |
|---|
| *.core | Определяет базовые классы, например ServiceHub |
|---|
| *.messages | Управляет событием обработчика сообщений |
|---|
| *.people | Определяет статус находящихся в сети пользователей |
|---|
| *.magiccarpet | Предоставляет классы и интерфейсы implementation-only |
|---|
В следующих шагах мы добавляем необходимые плагины как зависимости для плагина BuddyNote.
- Нажмите на вкладку Dependencies sample.buddynote в нижней части центрального окна.
Плагины org.eclipse.ui и org.eclipse.core.runtime уже должны быть в списке Required Plug-ins.
- Нажмите Add и добавьте следующее:
- com.ibm.collaboration.realtime.community
- com.ibm.collaboration.realtime.core
- com.ibm.collaboration.realtime.magiccarpet
- com.ibm.collaboration.realtime.messages
- com.ibm.collaboration.realtime.people
- com.ibm.rcp.realtime.livenames
- com.ibm.rcp.ui
Должен появиться экран, показанный на рисунке 3 (порядок плагинов неважен).
Рисунок 3. Необходимые для BuddyNote плагины
ПРИМЕЧАНИЕ: При добавлении этих зависимостей плагина при помощи мастера PDE к файлу MANIFEST.MF, который определяет плагин, добавляется следующее. Содержимое этого файла можно просмотреть, выбрав вкладку MANIFEST.MF, как показано в листинге 1.
Листинг 1. Плагин BuddyNote - MANIFEST.MF
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
com.ibm.collaboration.realtime.community,
com.ibm.collaboration.realtime.core,
com.ibm.collaboration.realtime.magiccarpet,
com.ibm.collaboration.realtime.messages,
com.ibm.collaboration.realtime.people,
com.ibm.rcp.realtime.livenames,
com.ibm.rcp.ui
|
ПРИМЕЧАНИЕ: Прежде чем продолжить, выберите File - Save All, чтобы позволить Eclipse считывать классы и интерфейсы, определённые в предыдущих плагинах, так как они потребуются на следующих этапах.
Определение расширений
В плагинах, входящих в состав Lotus Sametime, например тех, которые вы добавили как зависимости, декларируются точки расширения, в которых разработчики могут получить доступ к установленным классам и интерфейсам, использующимся при разработке. Точки расширения - это средство, при помощи которого можно расширить функциональность Lotus Sametime.
Для создания плагина BuddyNote необходимы следующие три точки расширения:
-
views. Позволяет определить визуальное приложение, отображающееся в Lotus Sametime.
-
shelfViews. Позволяет добавлять представление в виде окна к пользовательскому интерфейсу Lotus Sametime.
-
MessageHandlerListener. Уведомляет о событиях Lotus Sametime, например об отключении пользователя, получении сообщения, или, в случае BuddyNote, выборе контакта из Списка контактов.
Вы также можете определить точки расширения в создаваемых вами плагинах, чтобы позволить другим разработчикам расширять функциональность созданного вами плагина, однако эта возможность не рассматривается в этой статье.
Расширение views
Как уже было упомянуто, точка расширения views позволяет определить приложение, отображающееся в пользовательском интерфейсе Lotus Sametime; это первая точка расширения, которую следует определить для приложения BuddyNote.
- Нажмите на вкладку Extensions. Слева вы должны увидеть заголовок All Extensions, а под ним ничего не будет.
- Нажмите Add, а затем выберите расширение org.eclipse.ui.views из списка.
- Нажмите Finish. На появившейся панели вы теперь увидите заголовок "Extension Details" с полями данных ID, Name и Point. Значения в этих полях менять не нужно.
- Нажмите правой кнопкой мыши на добавленное расширение и выберите New - view.
- Выберите вновь добавленный элемент <view>. Обратите внимание, что Extension Element Details обновились и теперь отображают возможные атрибуты. Измените поля следующим образом:
id*: sample.buddynote.buddynoteview
name*: BuddyNote
class*: sample.buddynote.BuddyNoteView
Оставшиеся поля оставьте пустыми.
Звёздочка (*) обозначает необходимый атрибут. Особенно важен атрибут класса, обозначающий Java-класс, реализующий поведение представления (то есть этот класс определяет содержимое области просмотра, её реакцию на пользовательские события, и так далее).
Поле id используется для идентификации этого представления, когда мы позднее зададим точку расширения shelfViews, а поле name - это то, что отображается в строке заголовка представления.
- Нажмите на ссылку class*: attribute, чтобы открыть диалоговое окно New Java Class.
- Подтвердите следующую информацию:
Source folder: sample.buddynote/src
Package: sample.buddynote
Name: BuddyNoteView
Superclass: org.eclipse.ui.part.ViewPart.
ПРИМЕЧАНИЕ: если org.eclipse.ui.part.ViewPart не фигурирует в списке как суперкласс, нажмите Browse и введите ViewPart в текстовое поле Choose a type. В разделе Matching Types должно появиться ViewPart - org.eclipse.ui.part. Выберите эту запись и нажмите OK.
- Убедитесь, что информация в диалоговом окне New Java Class - такая же, как на рисунке 4.
Рисунок 4. Диалоговое окно New Java Class - BuddyNoteView
-
Нажмите Finish для создания класса BuddyNoteView. В центральном окне откроется редактор Java-классов с классом BuddyNoteView.java. См. Листинг 2.
Листинг 2. Класс BuddyNoteView
package sample.buddynote;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
public class BuddyNoteView extends ViewPart {
public BuddyNoteView() {
// TODO автоматически сгенерированный конструктор-заглушка
}
public void createPartControl(Composite arg0) {
// TODO автоматически сгенерированный метод-заглушка
}
public void setFocus() {
// TODO автоматически сгенерированный метод-заглушка
}
}
|
-
Выберите вкладку sample.buddynote в верхней части окна, чтобы отобразить вкладку Extensions редактора manifest-файлов плагина, с которым вы работали ранее. Выберите вкладку plugin.xml в нижней части окна и убедитесь, что её содержимое совпадает с кодом в Листинге 3.
Листинг 3. Плагин BuddyNote - plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension
point="org.eclipse.ui.views">
<view
class="sample.buddynote.BuddyNoteView"
id="sample.buddynote.buddynoteview"
name="BuddyNote"/>
</extension>
</plugin>
|
Как видно, редактор плагина помогает выполнить операции по созданию определения плагина и определений расширения плагина, автоматически обновляя файл plugin.xml. Хотя при желании можно ввести спецификации прямо в файл plugin.xml.
Теперь, когда мы определили представление BuddyNote, необходимо определить shelfView для его отображения.
Расширение shelfView
Для определения расширения shelfView выполните следующие операции:
- Вернитесь во вкладку Extensions и нажмите кнопку Add.
- Выберите расширение com.ibm.rcp.ui.shelfViews из списка.
- Нажмите Finish, и расширение появится в разделе views extension под All Extensions. Справа вы увидите Extension Details с полями данных ID, Name и Point. Эти значения менять не надо.
- Нажмите правой кнопкой мыши на расширение shelfViews и выберите New - shelfView для создания элемента shelfView.
- Появится диалоговое окно Extension Element Details. Измените данные в этих полях следующим образом:
id*: sample.buddynote.shelfView
view*: sample.buddynote.buddynoteview
region: BOTTOM
page: оставьте пустым
showTitle: true
Имейте в виду, что поле view содержит ID расширения представления, определённого вами ранее, указывающее представление, которое вы хотите отобразить во вновь определённой shelf. Если они не совпадают, представление BuddyNote не будет отображаться в Lotus Sametime.
Кроме того, для области отображения (region) указано значение BOTTOM (внизу), чтобы ваше приложение размещалось под Списком контактов. Если желаете, можете поэкспериментировать с этим атрибутом, и вы увидите, как представление BuddyNote перемещается из нижней части в верхнюю.
- Мы определили shelfView для отображения области просмотра. Выберите вкладку plugin.xml и сравните её содержимое с кодом в листинге 4.
Листинг 4. Плагин BuddyNote - plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension
point="org.eclipse.ui.views">
<view
class="sample.buddynote.BuddyNoteView"
id="sample.buddynote.buddynoteview"
name="BuddyNote"/>
</extension>
<extension
point="com.ibm.rcp.ui.shelfViews">
<shelfView
id="sample.buddynote.shelfView"
region="BOTTOM"
showTitle="true"
view="sample.buddynote.buddynoteview"/>
</extension>
</plugin>
|
Ранее мы определили расширение представлений и shelfViews, которые являются визуальным представлением BuddyNote. Следующее расширение, *messages.MessageHandlerListener, определяет класс, который будет получать уведомления о событиях в Lotus Sametime, например, когда в Списке контактов выбирается контакт.
Расширение MessageHandlerListener
Чтобы определить расширение MessageHandlerListener, выполните следующие шаги:
- Вернитесь на вкладку Extensions и нажмите кнопку Add.
- Выберите следующее расширение из списка: com.ibm.collaboration.realtime.messages.MessageHandlerListener.
- Нажмите Finish, и это расширение будет отображено ниже расширения shelfViews, под All Extensions. Справа вы увидите Extension Details с полями данных ID, Name и Point. Значения в этих полях менять не нужно.
- Нажмите правой кнопкой мыши на расширение MessageHandlerListener, а затем выберите New - messageHandler для создания элемента messageHandler.
- В правой части окна появится Extension Element Details с полями class, id и destinedMessagesOnly. Нас интересует только поле class. Введите в текстовое окно sample.buddynote.BuddyNoteMessageHandlerAdapter, а затем нажмите на ссылку class*.
- Откроется диалоговое окно New Java Class. Новый класс называется BuddyNoteMessageHandlerAdapter. Подтвердите следующую информацию:
Source Folder: sample.buddynote/src
Package: sample.buddynote
Name: BuddyNoteMessageHandlerAdapter
Superclass: com.ibm.collaboration.realtime.messages.MessageHandlerAdapter
ПРИМЕЧАНИЕ: Если com.ibm.collaboration.realtime.messages.MessageHandlerAdapter не фигурирует как суперкласс, нажмите Browse и введите MessageHandlerAdapter в текстовое окно Choose a type. Под Matching Types должно появиться MessageHandlerAdapter - com.ibm.collaboration.realtime.messages. Выберите его и нажмите OK.
- Убедитесь, что диалоговое окно New Java Class соответствует изображению на рисунке 5.
Рисунок 5. Диалоговое окно New Java Class - BuddyNoteMessageHandlerAdapter
-
Класс BuddyNoteMessageHandlerAdapter готов для редактирования. Вернитесь в manifest-редактор плагина, а затем выберите внизу вкладку plugin.xml. Убедитесь, что её содержимое совпадает с кодом в листинге 5, а затем выберите File - Save All.
Листинг 5. Плагин BuddyNote - plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension
point="org.eclipse.ui.views">
<view
class="sample.buddynote.BuddyNoteView"
id="sample.buddynote.buddynoteview"
name="BuddyNote"/>
</extension>
<extension
point="com.ibm.rcp.ui.shelfViews">
<shelfView
id="sample.buddynote.shelfView"
region="BOTTOM"
showTitle="true"
view="sample.buddynote.buddynoteview"/>
</extension>
<extension
point="com.ibm.collaboration.realtime.messages.MessageHandlerListener">
<messageHandler class="sample.buddynote.BuddyNoteMessageHandlerAdapter"/>
</extension>
</plugin>
|
Проверка работоспособности
Теперь у нас есть "скелет" плагина BuddyNote. Мы объявили точки, в которых он расширяет пользовательский интерфейс приложения Lotus Sametime, а также место, где он должен находиться. Для проверки "скелета" BuddyNote запустите Lotus Sametime и убедитесь, что плагин работает так, как ожидалось. Сначала обязательно закройте все другие экземпляры Lotus Sametime, запущенные на вашей машине.
На инструментальной панели Eclipse нажмите на стрелку справа от кнопки Run. Вы увидите список доступных конфигураций выполнения для тестирования. В данном случае имеется лишь одна опция, ST 751, как показано на рисунке 6.
Рисунок 6. Выпадающее меню
ПРИМЕЧАНИЕ: В данной статье мы используем этот способ запуска приложения. Можно также использовать строку меню, выбрав Run - Run и запустив ST 751 из появившегося диалогового окна, показанного на рисунке 7.
Рисунок 7. Диалоговое окно Run
ПРИМЕЧАНИЕ: Если вам предлагается выполнить сохранение после выбора ST 751, нажмите OK.
Вам будет предложено войти в Lotus Sametime. Используйте при входе свои обычные учетные данные.
Вы увидите изображение, показанное на рисунке 8.
Рисунок 8. Отображаемое окно BuddyNote
Окно BuddyNote можно свернуть в нижнюю часть окна программы. Для восстановления нажмите на заголовок окна.
Поздравляем! Вы зарезервировали место в Списке контактов Lotus Sametime для приложения BuddyNote. Теперь надо добавить Java-код, обеспечивающий необходимую функциональность, например, представление в виде визитной карточки для выбранного в данный момент контакта и текстовое поле внизу для добавления записей. Этот код приводится в данной статье. Рекомендуем вам ознакомиться с методами, чтобы понять, как сосуществуют некоторые объекты Lotus Sametime. Если интересно, можете также обратиться за справкой к JavaDoc, имеющейся в составе Lotus Sametime SDK (st751sdk\client\connect\javadoc\connect).
Добавление кода
Мы создали "скелет" BuddyNote, определив необходимые точки расширения; теперь, чтобы всё заработало, нужно добавить Java-код. Первый класс, который следует определить - BuddyNoteView, он создавался, когда мы определяли точку расширения views.
Начнём с заполнения переменных экземпляра, конструктора, а также некоторых helper-методов, неспецифичных для Lotus Sametime. После того как это будет сделано, перейдём к коду, отвечающему за расширение Lotus Sametime. Скопируйте и вставьте код, приведённый в соответствующих классах в центральном окне Eclipse. В листинге 6 приводятся переменные экземпляров и классов для BuddyNoteView.
Листинг 6. BuddyNoteView - переменные экземпляров и классов
static public BuddyNoteView INSTANCE;
private final String DEFAULT_NOTE = "<Click to enter notes>";
private Person person = null;
MyBusinessCard bizCard;
StyledText textControl;
String currentNote = null;
|
При создании класса был автоматически сгенерирован конструктор BuddyNoteView. В нём хранится ссылка на экземпляр области просмотра в переменной класса. Предполагается, что имеется лишь один экземпляр области просмотра BuddyNote. Замените или измените существующий конструктор таким образом, чтобы в нём присутствовал приведённый здесь код:
public BuddyNoteView () {
INSTANCE = this;
}
ПРИМЕЧАНИЕ: В Eclipse можно выбрать в меню Source - Organize Imports, чтобы добавить необходимые операторы импорта после вставки фрагмента кода. Рекомендуется делать так всякий раз после вставки прилагаемого кода.
При использовании Organize Imports у вас могут спросить, какой класс Person использовать. Обязательно выберите com.ibm.collaboration.realtime.people.Person, а не com.ibm.collaboration.realtime.imhub.SametimeConnectListParser.Person.
Здесь приведены краткие описания некоторых поддерживающих методов в данном классе. Вставьте их под методом createPartControl.
Метод getLocalFilespec, показанный в Листинге 7, служит посредником между идентификатором (login ID) пользователя Lotus Sametime и именем файла, который используется для хранения связанных с ним записей. В более продвинутой реализации записи хранятся в других местах, например, в серверной базе данных.
Листинг 7. BuddyNoteView - getLocalFilespec
private String getLocalFilespec(Person p) {
// Сохраняем BuddyNote в области метаданных плагина
// под названием person ID. Заменяем неверные символы
// спецификации файла, например, двоеточие.
StringBuffer sb = new StringBuffer();
String id = p.getId();
sb.append(Activator.getDefault().getStateLocation());
sb.append(File.separator);
for (int i=0; i < id.length(); i++) {
if (Character.isLetterOrDigit(id.charAt(i)))
sb.append(id.charAt(i));
else
sb.append('_');
}
sb.append(".txt");
return sb.toString();
}
|
В методе storeBuddyNote, показанном в Листинге 8, хранится запись (String s), связанная с объектом Person. Для упрощения реализации имя файла для сохраняемого текста такое же, как у идентификатора пользователя Lotus Sametime, и из него не удаляются какие-либо неверные для имени файла символы. Этот файл хранится в области, зарезервированной для плагинов. Она называется областью данных плагинов (в частности, это директория Eclipse runtime .metadata/.plugins/sample.buddynote).
Листинг 8. BuddyNoteView - storeBuddyNote
private void storeBuddyNote(Person p, String s) {
try {
String spec = getLocalFilespec(p);
File f = new File(spec);
// Удаляем файл, если новая запись - пустая
if (s == null || s.trim().length() == 0) {
f.delete();
return;
}
if (!f.exists())
f.createNewFile();
BufferedWriter out = new BufferedWriter(new FileWriter(f));
out.write(s);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
|
Метод retrieveBuddyNote, показанный в Листинге 9 считывает связанный с конкретным контактом текстовый файл, в котором хранятся все записи о нём. Как и в случае с storeBuddyNote, он на основании идентификатора пользователя Lotus Sametime конструирует имя файла и считывает этот файл из области данных плагина (в частности, из директории Eclipse .metadata/.plugins/sample.buddynote directory).
Листинг 9. BuddyNoteView - retrieveBuddyNote
private String retrieveBuddyNote(Person p) {
String s = null;
if (person != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
String spec = getLocalFilespec(p);
File f = new File(spec);
if (f.exists()) {
try {
BufferedReader in = new BufferedReader
(new FileReader(f));
String str;
while ((str = in.readLine()) != null) {
pw.println(str);
}
in.close();
s = sw.toString();
} catch (IOException e) {
}
}
}
return s;
}
|
Заполнение метода createPartControl
Этот метод отвечает за неспецифический для Sametime код. Давайте теперь взглянем на код, расширяющий Lotus Sametime, который создает область для BuddyNote в пользовательском интерфейсе и позволяет ей взаимодействовать с программой.
BuddyNote - это область просмотра. Области просмотра добавляют в Lotus Sametime видимые области. Эта область определяется в методе createPartControl с помощью стандартных виджетов Eclipse, называющихся SWT (Standard Widget Toolkit).
SWT API во многом похож на Java AWT (Abstract Window Toolkit) API. Виджеты SWT портируемы, а в инструментарий, помимо минимального набора для всех платформ, входят специальные виджеты (например, табличный виджет SWT целиком реализован на Java и запускается на всех поддерживаемых Eclipse платформах).
Cигнатура метода createPartControl уже должна быть автоматически добавлена Eclipse в класс BuddyNoteView. Убедитесь, что сигнатура метода createPartControl в вашем коде совпадает с нижеприведённым кодом:
public void createPartControl (Composite parent) {
Код метода начинается с формы, содержащей визитную карточку и текстовую область:
Composite comp = new Composite(parent, SWT.BORDER);
comp.setLayout(new FormLayout());
Затем код добавляет визитную карточку, как показано в листинге 10. Это виджет Lotus Sametime Connect, используемый для отображения информации о людях из Списка контактов. Вы можете узнать визитную карточку из окна чата Lotus Sametime.
Листинг 10. BuddyNoteView - визитная карточка createPartControl
// Визитная карточка "знает о контакте", то есть
// она будет обновляться при обновлении статуса контакта.
bizCard = new MyBusinessCard(comp, SWT.NONE);
FormData fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.left = new FormAttachment(0, 0);
fd.right = new FormAttachment(100, 0);
bizCard.setLayoutData(fd);
|
Затем мы определяем разделитель, разграничивающий визитную карточку и текстовую область, а затем инициализируем текстовую область, как показано в листинге 11.
Листинг 11. BuddyNoteView - текстовая область createPartControl
// Тёмная линия-разделитель между визитной карточкой и текстовой областью.
Label divider = new Label(comp, SWT.NONE);
divider.setBackground(divider.getDisplay().getSystemColor(
SWT.COLOR_DARK_GRAY));
fd = new FormData();
fd.top = new FormAttachment(bizCard, 0);
fd.left = new FormAttachment(0, 0);
fd.right = new FormAttachment(100, 0);
fd.height = 1;
divider.setLayoutData(fd);
// Область ввода текста; ничего не отображает,
// как определено в DEFAULT_NOTE
textControl = new StyledText(comp, SWT.MULTI |
SWT.V_SCROLL | SWT.WRAP);
fd = new FormData();
fd.top = new FormAttachment(divider, 0);
fd.bottom = new FormAttachment(100, 0);
fd.left = new FormAttachment(0, 0);
fd.right = new FormAttachment(100, 0);
textControl.setLayoutData(fd);
textControl.setText(DEFAULT_NOTE);
|
Для заполнения этого метода необходимо добавить для текстовой области детектор фокуса (focus listener), автоматически сохраняющий введённый текст, связанный с текущим контактом, в файл, проиндексированный идентификатор контакта Lotus Sametime, или возвращающий текст из файла, в зависимости от того, в фокусе или нет находится окно BuddyNote. См. листинг 12.
Листинг 12. BuddyNoteView - детектор фокуса createPartControl
// Сохраняем и восстанавливаем BuddyNote при наличии/отсутствии фокуса.
// (не забудьте, что сохранять записи по умолчанию не нужно!)
textControl.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
if (person != null && !textControl.getText().
equals(currentNote)) {
currentNote = textControl.getText();
storeBuddyNote(person, currentNote);
}
}
public void focusGained(FocusEvent arg0) {
if (person != null && textControl.getText().
equals(DEFAULT_NOTE))
textControl.setText("");
}
});
|
Последний фрагмент кода "просит" форму (составную) разместить созданные вами виджеты.
comp.layout();
Выберите File - Save All, а затем запустите пример, чтобы убедиться, что метод createPartControl выполняется, как ожидалось. Визитная карточка пуста, поскольку в коде не задан "контакт", который должен отображаться. Это будет сделано в следующем шаге. В текстовом поле "<Click to enter notes>" отображается текст по умолчанию, напоминание пользователю, что показано на рисунке 9.
Рисунок 9. Проверка работоспособности - BuddyNote Frame Layout
Определение обработки событий, связанных с сообщениями
Компоненты Lotus Sametime передают ключевые события через общую шину сообщений. Компоненты, использующие среду передачи сообщений, называются участниками (participants). Отправитель взаимодействует только с шиной сообщений, и ему не нужно ничего знать о компонентах, обрабатывающих сообщение.
Классы сообщений определяются для того, чтобы сделать создание и обработку сообщений простой и быстрой, а также обеспечить безопасность типов. Для каждого типа сообщений существует подкласс базового класса Message. Например, класс ImTextReceivedMessage представляет сообщение, передаваемое, когда пользователь получает входящее текстовое сообщение.
Интерфейс MessageHandler и класс DefaultMessageHandler обеспечивают отдельные методы для каждого типа подкласса Message. Можно сделать подклассом DefaultMessageHandler и переопределить методы handleMessage (подкласс Message) для тех сообщений, которые вы хотите обработать. Методы, которые не переопределяются явно, передаются в метод handleDefaultMessage подкласса. Этот подкласс DefaultMessageHandler обычно используется в связи с MessageHandlerAdapter.
Вот некоторые события, связанные с сообщениями, которые можно перехватывать через шины сообщений и соответствующим образом реагировать на них:
- handleMessage(ImChatWindowAdditionMessage)
- handleMessage(ImChatWindowCloseWarningMessage)
- handleMessage(ImChatWindowFlashWindowMessage)
- handleMessage(ImChatWindowForceFocusMessage)
- handleMessage(ImChatWindowToolbarRedrawMessage)
- handleMessage(ImConnectedMessage)
- handleMessage(ImConnectionStatusChangeMessage)
- handleMessage(ImDisconnectedMessage)
- handleMessage(ImTextConnectionClosedMessage)
- handleMessage(ImTextConnectionOpenMessage)
- handleMessage(ImTextReceivedMessage)
- handleMessage(ImTextSendMessage)
Мы создали класс MessageHandlerAdapter под названием BuddyNoteMessageHandlerAdapter, когда настраивали расширение MessageHandlerListener. Затем мы будем заполнять этот класс, включив в него вызов класса MessageHandler под названием BuddyNoteMessageHandler, который также будет создан.
BuddyNoteMessageHandler переопределяет методы handleMessage(BuddySelectedMessage) и handleMessage(ImConnectedMessage). Эти методы позволяют приложению BuddyNote запускаться, отображая по умолчанию вашу информацию, а также обновляться в зависимости от того, какие контакты вы затем выбираете.
BuddyNoteMessageHandlerAdapter
Адаптер обработчика сообщений указывается в manifest-файле расширений как класс, связанный с точкой расширения *messages.MessageHandlerListener. Мы добавили эту точку расширения как зависимость плагина BuddyNote в начале статьи, а также определили связанный класс как BuddyNoteMessageHandlerAdapter.
Если нажать на вкладку sample.buddynote в центральном окне Eclipse, а затем выбрать внизу вкладку plugin.xml, вы увидите код, приведённый в Листинге 13.
Листинг 13. Точка расширения MessageHandlerListener
<extension
point="com.ibm.collaboration.realtime.messages.MessageHandlerListener">
<messageHandler class="sample.buddynote.BuddyNoteMessageHandlerAdapter"/>
</extension>
|
Код BuddyNoteMessageHandlerAdapter приведён в Листинге 14. Eclipse уже создал две сигнатуры конструкторов, и добавлять никакие другие методы не нужно.
Листинг 14. Класс BuddyNoteMessageHandlerAdapter
public class BuddyNoteMessageHandlerAdapter extends MessageHandlerAdapter {
public BuddyNoteMessageHandlerAdapter(MessageHandler handler) {
super(handler);
}
public BuddyNoteMessageHandlerAdapter() {
super (new BuddyNoteMessageHandler());
}
}
|
Код адаптера просто определяет подходящий для использования обработчик сообщений. В более сложном случае в адаптере можно разместить код инициализации, необходимый для обработчика (обработчиков).
Как вы видите, конструктор по умолчанию использует объект BuddyNoteMessageHandler. Именно этот класс выполняет реальную работу по обработке входящих событий; это подкласс DefaultMessageHandler. Далее мы создадим этот класс и определим его.
BuddyNoteMessageHandler
BuddyNoteMessageHandler содержит необходимый код для обнаружения выбранного пользователем контакта, вызова метода для наполнения визитной карточки информацией о контакте, определения статуса соединения пользователя, а также вызова метода, который вводит в визитную карточку данные о пользователе при запуске.
Для создания класса выполните следующие шаги:
- Выберите пакет sample.buddynote в Package Explorer.
- Выберите New - Class и введите следующую информацию:
Source Folder: sample.buddynote/src
Package: sample.buddynote
Name: BuddyNoteMessageHandler
Superclass: com.ibm.collaboration.realtime.messages.DefaultMessageHandler
ПРИМЕЧАНИЕ: Выберите Browse и введите DefaultMessageHandler в текстовое окно Choose a type. Под Matching Types появляется DefaultMessageHandler - com.ibm.collaboration.realtime.messages. Выберите его и нажмите OK.
- Убедитесь, что информация в диалоговом окне New Java Class - такая же, как на рисунке 10.
Рисунок 10. Диалоговое окно New Java Class - BuddyNoteMessageHandler
- Нажмите Finish для создания класса.
BuddyNoteMessageHandler имеет один переопределённый метод - handleMessage. Они используют методы из классов BuddyNoteView, handleBuddySelected и handleConnected, с которыми мы столкнёмся далее. Поэтому не обращайте внимания на ошибки компилятора в Eclipse, относящиеся к неопределённым методам, так как они рассматриваются в следующем разделе.
Событие handleMessage(BuddySelectedMessage message) уведомляет одноэлементное множество BuddyNote при помощи своего метода handleBuddySelected. Он реагирует, помещая информацию о выделенном пользователе в визитную карточку, которую мы инициализировали ранее в методе createPartControl BuddyNoteView.
В коде листинга 15 используется ServiceHub Lotus Sametime для извлечения сервиса зарегистрированных контактов; этот сервис превращает mapping ID (строка, состоящая из логина пользователя и идентификатора сообщества) в экземпляры контактов.
Листинг 15. BuddyNoteMessageHandler - handleMessage(BuddySelectedMessage message)
public void handleMessage(BuddySelectedMessage message) {
try {
PeopleService peopleSvc = (PeopleService) ServiceHub.
getService(PeopleService.SERVICE_TYPE);
Person person = peopleSvc.getPersonById(
message.getPersonId());
BuddyNoteView.INSTANCE.handleBuddySelected(person); }
catch (ServiceException e) {
e.printStackTrace();
}
}
|
Событие handleMessage(ImConnectedMessage) уведомляет одноэлементное множество области просмотра BuddyNote с помощью своего метода handleConnected. Он реагирует, помещая информацию о вошедшем в систему пользователе в визитную карточку при запуске. Другими словами, визитная карточка в окне BuddyNote отображает данные вашей визитной карточки, пока вы не выберете другую в Списке контактов.
public void handleMessage(ImConnectedMessage message) {
BuddyNoteView.INSTANCE.handleConnected();
}
Напоминание: выбрав в меню Source - Organize Imports, добавьте необходимые операторы импорта после вставки фрагмента кода. При запросе обязательно выберите com.ibm.collaboration.realtime.people.Person, а не com.ibm.collaboration.realtime.imhub.SametimeConnectListParser.Person.
Проигнорируйте все ошибки, относящиеся к неопределённым методам, так как эти ошибки исчезнут, как только будет добавлен остальной код.
Завершение работы над BuddyNoteView
Теперь, когда обработчик сообщений и адаптер завершены, добавим к BuddyNoteView методы, реагирующие на эти сообщения в области просмотра. Эти методы зависят от двух других, getLocalPerson и refreshPersonInfo, речь о них пойдёт далее.
Метод handleConnected вызывается из BuddyNoteMessageHandler при обнаружении подключения Lotus Sametime. В этом случае в визитную карточку вводится информация по умолчанию о вошедшем в систему пользователе, пока тот не выберет контакт. См. листинг 16.
Листинг 16. BuddyNoteView - handleConnected
void handleConnected() {
// инициализация текущего пользователя, если не выбран никакой другой
if (person == null) {
person = getLocalPerson();
refreshPersonInfo(person);
}
}
|
Метод handleBuddySelected вызывается из BuddyNoteMessageHandler, когда он обнаруживает, что вы выбрали кого-то из Списка контактов. В этом случае визитная карточка обновляется и отображает информацию по выбранному в данный момент контакту. См. Листинг 17.
Листинг 17. BuddyNoteView - handleBuddySelected
void handleBuddySelected(Person person) {
this.person = person;
refreshPersonInfo(person);
}
|
Метод refreshPersonInfo обновляет визитную карточку, отображая информацию по выбранному контакту, либо вашу собственную информацию, если Lotus Sametime только что подключился. В разделе записей выводится запись, которая хранилась для этого контакта, либо, если ни один контакт не выбран, выводится текст по умолчанию ("<Click to enter notes>"). См. Листинг 18.
Листинг 18. BuddyNoteView - refreshPersonInfo
private void refreshPersonInfo(final Person person) {
// Уведомления в Sametime Connect часто приходят от
// non-UI threads. Поставьте в очередь запрос к UI thread.
bizCard.getDisplay().asyncExec(new Runnable() {
public void run() {
if (textControl.isDisposed())
return;
bizCard.setPerson(person);
currentNote = retrieveBuddyNote(person);
if (currentNote != null)
textControl.setText(currentNote);
else
textControl.setText(DEFAULT_NOTE);
}
});
}
|
Метод getLocalPerson - последний метод, необходимый для правильной работы плагина BuddyNote. При первом подключении Lotus Sametime с помощью Community и PeopleService, в разделе визитной карточки отображаются ваши данные. В Community содержится список известных сообществ (Lotus Sametime, внешние IM-сети и так далее), а PeopleService обрабатывает соответствия между идентификаторами контактов и реальными людьми. См. Листинг 19.
Листинг 19. BuddyNoteView - getLocalPerson
private Person getLocalPerson() {
// Возвращаем local person (для первоначального отображения)
Person p = null;
try {
CommunityService communityMgr = (CommunityService)
ServiceHub.getService
(CommunityService.SERVICE_TYPE);
Community community = communityMgr.getDefaultCommunity();
if (null != community) {
String localUserId = community.getUserId();
if (localUserId != null) {
PeopleService peopleSvc = (PeopleService)
ServiceHub.
getService(PeopleService.SERVICE_TYPE);
p = peopleSvc.getPerson(
localUserId, community.getId());
}
}
} catch (ServiceException e) {
e.printStackTrace();
}
return p;
}
|
Запуск плагина BuddyNote
Теперь, когда мы добавили весь необходимый код, всё, что осталось сделать - протестировать плагин и при необходимости отладить его. Сначала выберите File - Save All, а затем убедитесь в отсутствии ошибок, посмотрев на представление Problems, как показано на рисунке 11.
Рисунок 11. Представление Console - вкладка Problems
Если в списке отображаются какие-либо проблемы, дважды щёлкните по ним. Eclipse отобразит код, вызывающий данные ошибки. Слева от проблемной строки появится красный крестик; при нажатии на него будут выведены рекомендации по исправлению ошибки. См. рисунок 12.
Рисунок 12. Пример ошибки
Прежде чем пытаться исправить эти ошибки, попробуйте применить Source - Organize Imports, поскольку отсутствующий оператор импорта - наиболее вероятная причина ошибки. Если проблема не исчезнет, прибегните к рекомендуемым действиям.
Если же ошибок нет, запустите приложение с помощью ST 751 из выпадающего меню, как вы уже это делали в этой статье. Подождите несколько секунд, пока Lotus Sametime не запустится. Войдите в систему при помощи ваших ID и пароля, и вы увидите что-то очень похожее на рисунок 1.
Поздравляем, вы создали свой первый плагин Lotus Sametime!
Заключение
В данной статье рассмотрены шаги по созданию расширения области просмотра Lotus Sametime. Вы узнали, как создавать плагин, расширения плагина и классы, определяющие поведение этих новых расширений. Наконец, мы протестировали новый код в PDE Eclipse.
В следующей, третьей, части данной серии демонстрируется использование инструментов отладки, встроенных в Eclipse, для поиска и устранения ошибок, с которыми вы можете столкнуться при разработке плагина. А в части 4, последней в серии, будет рассмотрен процесс развёртывания плагина с помощью сайта обновления.
Загрузка | Имя | Размер | Метод загрузки |
|---|
| BuddyNote_Workspace.zip | 1428KB | HTTP | | BuddyNoteCode.txt | 8KB | HTTP |
Ресурсы Научиться
Получить продукты и технологии
Обсудить
Об авторах  | |  | Дэн Кен (Dan Kehn) – старший разработчик ПО IBM в Research Triangle Park, Северная Каролина. У него есть большой опыт работы с разнообразным ПО. Он имел дело со средствами разработки, например Rational Application Developer, а также работал над увеличением производительности операционных систем, анализом памяти и проектировал пользовательские интерфейсы. Он также является соавтором получившей награды книги Руководство Java-разработчика по Eclipse (The Java Developer's Guide to Eclipse). В настоящее время он работает техническим специалистом по внедрению (Technical Enablement Specialist) и помогает партнёрам по бизнесу интегрировать их продукты в IBM Lotus Sametime Connect. |
 | |  | Лоренс Райт - студент и сотрудник Государственного университета Северной Каролины, имеющий степень бакалавра наук в области электротехники. В настоящее время он готовится к получению степени бакалавра по информатике. |
Выскажите мнение об этой странице
|  |