Реализация интерфейса
Реализация интерфейса при написании системы «EZSurf» вызвала немало сложностей, по большей части, потому что толком никакой информации о создании интерфейсов для мультиагентных систем найдено не было. Изначально было задумана полная реализация интерфейса на JavaFX, необходимо было, каким то образом, создавать экземпляр агента и передавать его контроллеру, однако возникла проблема с потоками JADE агентов и JavaFX Application Thread, при исполнении которых возникали исключительные ситуации.
В итоге при реализации интерфейса использовались две стандартных библиотеки Java Swing и JavaFX (начиная с JDK 1.7). Был найден способ использования отдельных компонентов интерфейса библиотеки JavaFX в Java Swing фрейме, который в свое время мог принимать экземпляр агента в качестве параметра в конструкторе. Такой подход позволил создавать окно приложения из потока агента в методе setup посредством передачи в конструктор объекта формы указателя на самого себя – this (см. стр. Приложения текст программы строка…).
Весь интерфейс прописан в классе CollectorGuiAuth.java (см. Рис. 14), который наследует класс JFrame – стандартный класс Java Swing для создания форм приложения. Из-за такого не стандартного подхода к созданию интерфейса, все состояния интерфейса рисуются на одном и том же фрейме, посредством установки свойства видимости компонентов в значение false и динамического создания компонентов. То есть экраны разные, но объект используется для их отображения один и тот же.
На первом экране приложения использованы компоненты библиотеки JavaFX WebView, WebEngine и компонент библиотеки Java Swing – JFXPanel, который позволил встроить JavaFX объекты в JFrame(Рис. 10).
Рисунок 10. Первый экран приложения – Авторизация “ВКонтакте” На втором экране после успешного прохождения авторизации появляется экран с кнопкой запуска основного функционала. JFXPanel принимает значение видимости false, и создается объект обычной JPanel из библиотеки Java Swing (Рис. 11).
Рисунок 11. Второй экран приложения – Запуск сбора, обработки, анализа На третьем экране снова понадобился компонент из библиотеки JavaFX – ProgressIndicator. Для того чтобы наглядно показать процесс сбора, обработки, анализа данных добавляем JFXPanel с ProgressIndicator на основной фрейм, а у JPanel второго экрана устанавливаем свойство видимости в значение false (Рис. 12).
Рисунок 12. Третий экран приложения – индикатор процесса обработки, сбора и анализа данных
Четвертый экран – последний, показывает результаты работы системы – рекомендации. Обратно возвращается JPanel, делая не видимой JFXPanel, и динамически создаются блоки рекомендации. Каждый блог предствляет собой JLabel – заголовок статьи по нажатию на который статья открывается в браузере, JLabel созданный из объекта ImageIcon, который в свою очередь создан из URL обложки статьи, и JTextArea – описания статьи (Рис. 13).
Рисунок 13. Последний экран приложения – результаты работы системы
Реализация агентов
Для удобства разъяснения реализации агентов ниже представлена диаграмма классов системы “EZSurf” (Рис. 14). Для создания агентов использовалась сторонняя библиотека JADE(Java Agent Development Environment), каждый агент представлен отдельным классом, который наследует класс jade.core.agent.
Рисунок 14. Диаграмма классов системы «EZSurf» Все агенты инициализируется при запуске программы. Происходит вызов метода setup всех трех агентов. Дальнейшее взаимодействие происходит посредством обмена ACL сообщениями, где JADE создает очередь и управляет потоком ACL-сообщений[10].
Агент Сборщик представленный классом Collector, в котором происходит сбор данных из профиля пользователя в социальной сети “ВКонтакте”, также отвечает за создание окна приложения в методе setup, который вызывается при создании агента. После того как пользователь авторизуется “ВКонтакте”, и нажмет кнопку «SURF» сработает обработчик событий actionPerformed в классе CollectorGuiAuth, в котором происходит вызов метода агента onGuiEvent, который в свою очередь производит вызов метода сбора данных(collectData). Перед тем как начать собирать новые данные метод clearDBs удаляет данные из базы по текущему пользователю.
Метод сбора данных использует объект класса VKCommunication, содержащий методы вызова VK API для получения списков аудио, видео и персональной информации, в которых также происходит парсинг JSON ответов для получения нужных данных. В случае с аудио это исполнитель. На рисунке 15 представлен пример ответа на вызов метода audio.get из VK API.
Рисунок 15. JSON ответ на вызов метода VK API audio.get По окончанию сбора данных происходит отправление ACL сообщения агенту Анализатору при помощи средств библиотеки JADE, класса ACL Message.
Агент Анализатор представленный классом Analyzer на диаграмме классов (Рис. 14) производит вызов методов API LastFM и TheMovieDB для сбора схожих объектов для аудио и видео соответственно. Затем Анализатор посылает ACL сообщение-сигнал агенту Рекомендателю. На рисунке 16 виден результат работы Анализатора, во второй колонке информация об объекте, в третьей колонке id объекта для которого, данный объект является схожим и в четвертой колонке тип объекта.
Рисунок 16. Таблица recommendation Получив сообщение о начале поиска, Рекомендатель (класс Recommender), по сути, поисковый робот, производит индексацию каждого сайта из реестра, где реестр представляет собой таблицу базы данных, содержащую URL сайта и тип контента, который может быть найден на этом сайте (Рис. 17). Индексация страниц происходит в классе Crawler по следующему алгоритму:
Рисунок 17. Таблица registry
Код
| Тип контента
| 0
| Интересы
| 1
| Музыка
| 2
| Видео
| 3
| Все типы
| Таблица 2. Расшифровка значений колонки type в таблице registry.
Загрузить страницу с адресом pageURL.
Поместить адрес pageURL в список посещенных страниц.
Найти ссылки на загруженной странице с адресом pageURL.
Для каждой найденной ссылки не находящейся в списке посещенных страниц запустить процедуру из пункта 1.[11]
Таким образом, выходит, что алгоритм использует рекурсивный вызов, что означает большую трудоемкость и ресурсоемкость. Однако если для каждого сайта запустить данный алгоритм в разном потоке параллельно, то это ускорит процесс. Также для управления заданиями и потоками использованы такие структуры данных как пул потоков - ThreadPoolExecutor и связанная блокирующая очередь – LinkedBlockingQueue[11] из стандартной библиотеки java.util, что также позволяет оптимизировать данный процесс. Если создано заданий больше чем может пул потоков обработать одновременно, то задачи простаивают в этой очереди, и время их жизни задается в конструкторе пула потоков. В данном случае время жизни заданий 5 минут. За хранение адресов уже посещенных страниц отвечает такая структура данных как hash map из той же библиотеки java.util.
Рисунок 18. Схема алгоритма индексации [11] В процессе каждая страница проверяется на наличие рекомендательного контента. Из таблицы recommendation в структуру данных List записывается колонка rec_info. В rec_info будет записано имя артиста, название видео или хобби, в случае если в колонке type значение audio, video или hobby соответственно. Для каждого объекта в этом List, выявленного анализатором, как рекомендуемого, происходит поиск совпадений на странице. С помощью сторонних библиотек Jericho и jSoup происходит извлечение содержимого мета тегов title, description и keywords. Если хотя бы в одном из мета тегов присутствует вхождение искомой строки и хотя бы одно вхождение найдено в теле HTML страницы, то есть внутри тега body, то страница принимается за рекомендуемую. Содержимое тегов title и description записываются в базу результатов как заголовок и описание статьи соответственно.
|