Примечание редактора: Обладаете глубокими знаниями по данной теме? Хотите поделиться своей компетентностью? Примите участие в Wiki-программе по продуктам IBM Lotus.
| Lotus Quickr wiki |
|---|
Статистические данные по отдельным местам (place) содержат полезную информацию о местах, включая количество документов в конкретном месте, количество измененных сегодня документов, количество документов в библиотеке и т.д. Эта информация полезна для владельцев мест и для администратора сервера. Кроме того, эту статистику можно просматривать с помощью простого пользовательского интерфейса, доступного из темы, а также загружать в формате CSV, который импортировать в электронную таблицу.
В этой статье мы сделаем эти статистические данные более удобными для использования владельцами мест. Мы собираемся сделать следующее:
- Разработать сервлет для получения доступа к фидам Place Statistics
- Применить Abdera для вызова adminqcs-фидов, для построения Atom-фидов и для разбора XML
- Использовать API-интерфейс WebSphere Portal для связывания фидов JSON
- Защитить новый сервлет
- Написать Dojo-виджет, который будет поддерживать простой интерфейс пользователя и предоставлять средства для загрузки CSV-файла
- Интегрировать этот виджет с темой Lotus Quickr
Полученный в итоге интерфейс пользователя в удобной форме демонстрирует владельцам мест статистику о контенте, о росте и о «здоровье» соответствующего места.
Все необходимые материалы для развертывания виджета Place Statistics содержатся в EAR-файле, приложенном к этой статье. В разделе «Развертывание» описывается, как установить этот виджет и как внести в тему изменения, позволяющие получить доступ к новой функции.
Начнем с построения сервлета для получения статистических данных о месте. Этот сервлет использует существующий фид \adminqcs, добавляя к нему возможности для вывода сведений в формате JSON. Вывод в формате JSON упрощает использование JavaScript-компонентов в выходном фиде.
На рис. 1 показано, как взаимодействуют компоненты сервлета. После поступления запроса выполняется получение данных из фида \adminqcs в формате Atom или в формате CSV в зависимости от необходимого конечного формата. Извлечение данных осуществляется с помощью компонента FeedRetriever. Затем эти данные передаются в компонент FeedHandler, который обеспечивает вывод статистических данных в надлежащем формате. К примеру, если нам нужен формат JSON, мы получаем вывод в формате JSON, а не в формате Atom или CSV.
Рис. 1. Сервлет Place Statistics
Статистические данные места могут быть получены любым лицом с ролью менеджера этого места или любым лицом с ролью, имеющей полномочия Manage Membership (управление членством).
Сервлет Place Statistics, описанный в этой статье, не предоставляет никаких дополнительных возможностей авторизации. Класс PlaceStatisticsRetriever в примере программного кода содержит метод authenticateAccess (), который можно использовать для выполнения дополнительной авторизации. При реализации этого метода он выдает исключение bcrk.xtybtPlaceStatisticsAuthenticationException, если текущему пользователю не разрешено просматривать статистику. Метод authenticateAccess() вызывается до получения статистических данных места.
Feed retriever: Потребление фида Place Statistics
Существующий фид \adminqcs Place Statistics предоставляет сведения в формате Atom или в формате CSV. Формат Atom легко разбирается с использованием Java-кода и обеспечивает структурированное представление статистики места. Фид в формате CSV может быть загружен в файл из браузера, однако его трудно использовать для какой-либо другой цели.
Для извлечения каждого из этих фидов требуется свой программный код, поскольку они представляются в различных форматах; CSV представляется в виде потока, а Atom оформлен в виде XML-документа. Необходимое нам поведение является общим для двух форматов, поэтому оно может быть выражено с помощью интерфейса, реализуемого каждым из создаваемых нами компонентов типа feed retriever («извлекатель фида»). Этот интерфейс показан в Листинге 1.
Листинг 1. Интерфейс #BaseFeedRetriever
package com.ibm.quickr.placestatistics.datahandler;
import javax.servlet.http.Cookie;
import com.ibm.quickr.placestatistics.exceptions.PlaceStatisticsException;
public interface BaseFeedRetriever {
public Object getFeed(String feedUrl, Cookie[] cookies)
throws PlaceStatisticsException;
}
|
Метод getFeed () в качестве входа берет URL-адрес, от которого мы хотим получать фид (в т.ч. любые параметры, например, интервал дат), и cookie-файлы, необходимые для аутентификации. Сервис \adminqcs использует LTPA-маркеры (cookie-файлы), которые продукт WebSphere Portal задействует для аутентификации.
Мы создаем классы, расширяющие этот интерфейс, которые предоставляют свою собственную реализацию метода getFeed (). Чтобы гарантировать использование надлежащей реализации компонента чтения фида (feed reader), мы также создаем factory-класс, который предоставляет подходящий компонент feed reader исходя из желаемого выходного формата. Если требуется вывод в формате CSV, применяется компонент CSVFeedRetriever. Во всех остальных случаях применяется компонент AtomFeedRetriever, поскольку результирующий Atom-документ может быть затем подвергнут разбору для преобразования в другие форматы, например, JSON.
Если станут доступны другие типы выходных данных сервиса \adminqcs, вы сможете создать класс для обработки фидов этих типов без ущерба для классов, обрабатывающих фиды в форматах Atom и CSV.
Класс AtomFeedRetriever используется для получения Atom-версии фида Place Statistics.
С помощью Apache Abdera подается HTTP-запрос к сервису \adminqcs. Кроме того, Abdera используется для обработки возвращенных данных и для выполнения некоторых других действий в рамках проекта. Нам потребуются экземпляр класса AbderaClient и экземпляр класса RequestOptions, которые будут использоваться для передачи (в рамках запроса) любых опций, таких как cookie-файлы.
Один из параметров в методе getFeed представляет собой массив cookie-файлов. Некоторые из cookie-файлов в исходном запросе сервлета представляют собой cookie-файлы LTPA, которые продукт WebSphere Portal использует для аутентификации. Сначала создается экземпляр класса org.apache.abdera.protocol.client.RequestOptions, а затем настраиваются детали cookie-файлов. Cookie-файлы должны быть определены как массив строк, по одной строке на каждый cookie-файл, при этом каждая строка имеет форму:
name = value
Мы осуществляем прохождение по cookie-файлам и формируем строковый массив, каждый элемент которого соответствует одному cookie-файлу, а затем используем этот массив для настройки объекта RequestOptions, как показано в листинге 2.
Листинг 2. Настройка cookie-файлов для запроса
RequestOptions options = new RequestOptions(true);
// Put the cookies onto the request options.
List<String> cookieStrings = new ArrayList<String>();;
for (int i=0; i<cookies.length;i++) {
String name = cookies[i].getName();
String value = cookies[i].getValue();
cookieStrings.add(name+"="+value);
}
options.setHeader("Cookie", (String[])cookieStrings.toArray
(new String[cookieStrings.size()]));
|
Сам запрос создается с помощью метода get() в экземпляре AbderaClient посредством передачи URL-адреса для запроса и настроенного нами объекта RequestOptions. Ответ представляет собой экземпляр Abdera-класса ClientResponse, содержащий сведения о состоянии ответа (например, успех или неудача), и данные, отправленные в ответе. В этом экземпляре (при условии успешного ответа) ответ содержит XML-документ Atom. Этот документ можно извлечь с помощью метода getResponse() экземпляра ClientReponse. В случае ошибки генерируется соответствующее исключение, которое затем обрабатывается.
Полученный ответ пересылается как вывод компонента feed reader, готовый к использованию в любом месте.
Получение CSV-фида аналогично получению Atom-фида Place Statistics. Единственная практическая разница состоит в обработке результатов запроса.
Как и в предыдущем случае, необходимо задать cookie-файлы для обработки объекта RequestOptions и последующей отсылки запроса
На этот раз мы получаем возвращенный CSV-фид в форме фида InputStream, который необходимо прочесть. Хороший вариант – использование компонента BufferedReader для побитового чтения данных из фида. Каждый прочитанный нами бит добавляется к объекту StringBuffer – до тех пор, пока есть что читать. После этого можно возвратить StringBuffer из retriever в качестве выходных данных.
Теперь, когда у нас есть данные Place Statistics в формате Atom или CSV, необходимо сформировать выходные данные, которые посылаются вызывающей стороне нашего сервлета в запрошенной форме.
Ради аккуратности и гибкости можно для обработки каждого выходного формата использовать отдельный класс, который обладал бы функциональностью, описанной в Таблице 1.
Таблица 1. Функции класса для вывода статистических данных
| Функция вывода | Подробное описание |
|---|---|
| Handle statistics feed | Берет фид статистики и записывает его в требуемом формате в соответствующий выходной фид. |
| Provide content type | Предоставляет средства для извлечения типа контента выходного формата. После создания экземпляра FeedHandler с помощью этого метода можно быть получить тип контента для фида. |
| Write exception output | Выходные данные исключения в заданном формате. Например, если исключение происходит при обработке AtomHandler, эта функция записывает данные исключения в формате Atom. |
Поскольку операции этих классов аналогичны, можно создать интерфейс, определив в нем контракт, который будут реализовывать все наши классы. Пример интерфейса BaseFeedHandler показан в листинге 3.
Листинг 3. Интерфейс BaseFeedHandler
public interface BaseFeedHandler {
// Method to produce feed for an exception.
public Object produceExceptionFeed
(Exception ex, PrintWriter writer, String feedId);
public void handleStatsFeed(Object feed, PrintWriter writer)
throws PlaceStatisticsException;
public String getContentType();
}
|
Тип фида, поступающего в метод handleStatsFeed, зависит от требуемого типа выходного фида. Например, если мы обрабатываем Atom-фид, то вышеупомянутый фид имеет тип Abdera; если мы обрабатываем CSV-фид, то фид имеет тип StringBuffer.
AtomFeedHandler выводит фид Place Statistics в формате Atom. Нам достаточно взять Atom-фид, полученный от сервиса \adminqcs, и передать его наружу с помощью ответа для сервлета.
JSONFeedHandler выводит фид Place Statistics в формате JSON и требует немного большего объема работы. Функция handleStatsFeed ожидает поступление Atom-фида, порожденного сервисом adminqcs.
Handler выводит JSON-структуру, которая позволяет описать фид статистических данных для места; например:
{id : "statistics", fromDate : "2010-05-27", toDate : "2010-05-30",
title: "Lotus Quickr Admin Feed", items: [{"published", statistics:
[{key: "document_totalNum", value: 1}]}]}
Первая часть фида содержит идентификатор (ID) фида, начальную и конечную даты фида, а также заголовок фида. Затем следует массив элементов, каждый элемент которого соответствует одному элементу <entry> в Atom-фиде.
Каждый элемент содержит дату публикации, заголовок и последующий массив. Этот массив содержит статистическую информацию для места, при этом каждый его элемент имеет ключ и значение. Ключ идентифицирует компонент статистических данных (пример: document_size), а значение, соответственно, указывает на значение этого компонента.
Мы используем для разбора Atom-фида приложение Abdera, поскольку Abdera предоставляет все необходимое для разбора DOM — непосредственного или с помощью Xpath-запросов. В процессе разбора мы можем создать свою JSON-структуру с помощью API-интерфейсов WebSphere Portal. Эти интерфейсы обрабатывают любые проблемы со специальными символами и кодированием, сокращая перечень поводов для беспокойства.
В Приложении 1 показан стандартный Atom-фид для статистики места. Abdera существенно упрощает разбор этого фида в формат JSON.
Сначала осуществляется получение списка записей в Atom-фиде, затем в этих записях ищется элемент <statistics>, который содержит информацию статистики места. После нахождения этого элемента осуществляется итерационный просмотр элементов в пределах соответствующей записи с помощью JSON-пар, сформированных для каждого компонента статистических данных.
Создается экземпляр класса JSONHandler, и несколько методов этого экземпляра используются для создания JSON-структуры. Подробные сведения об этих методах предоставлены в таблице 2.
Таблица 2. Методы JSON-обработки, предоставляемые классом JSONHandler
| Метод API-интерфейса | Описание |
|---|---|
| startJsonObject | Начинает JSON-объект. Эквивалентен вводу в структуру открывающей фигурной скобки ({). |
| jsonPair(key, value) | Вставляет в структуру пару ключ- значение: fromDate : “2010-05-27” |
| startArray() | Начинает массив в структуре. Эквивалентен вводу открывающей квадратной скобки ([). |
| startPair(pairkey) | Начинает JSON-пару с переданного ключа. |
| endPair() | Завершает пару, ранее начатую методом startPair. |
| endArray() | Завершает массив, начатый методом startArra. Фактически вводит в структуру закрывающую квадратную скобку (]). |
| endJsonObject | Завершает JSON-объект, начатый методом startJsonObject. Фактически вводит в структуру закрывающую фигурную скобку (}). |
Иногда происходят ошибки, и пользователю необходимо знать об этом.
Каждый из обработчиков FeedHandler должен быть в состоянии отослать подробности произошедших исключений в соответствующем формате. Например, Atom FeedHandler отсылает Atom-документ, содержащий подробности ошибки, JSON FeedHandler отсылает JSON-документ и т. д. Если мы не сделаем этого, то JSON-обработчик вызова xhrGet, используемого для получения фида Place Statistics, может обнаружить, что он передает обратно отчет об исключениях Atom, с которым он не знает, что делать.
AtomFeedHandler использует Abdera для создания Atom-фида, содержащего подробности исключения. Экземпляр класса FOMFactory используется для генерации нового фида с подробностями исключения, добавляемого в этот экземпляр. Затем все это отсылается обратно вызывающей стороне. В примере в следующем листинге показана генерация Atom-фида для исключения.
Листинг 4. Пример программного кода, генерирующего Atom-фид для исключения
public final Object produceExceptionFeed(Exception ex,
PrintWriter writer, String feedId) {
Feed feed = factory.newFeed();
// Produce the feed header.
this.produceFeedHeader(feed, MessageHelper.getMessageFromBundle
("statistics.feed.title"), feedId);
// Add an entry in to show the error.
Entry entry = factory.newEntry();
entry.setTitle(MessageHelper.getMessageFromBundle
("statistics.feed.exceptiontitle"));
entry.setContent(ex.getMessage());
feed.insertEntry(entry);
try {
this.writeFeed(writer, feed);
} catch (Exception e) {
e.printStackTrace();
}
return feed;
}
|
Выходная информация JSONFeedHandler об исключении представлена в формате JSON. Объекты API-интерфейса WebSphere Portal, использовавшиеся для формирования JSON-вывода, который мы уже видели раньше, теперь используются для формирования новой структуры. Экземпляр com.ibm.portal.streaming.json.JSONHandler используется для создания документа, к которому добавляются JSON-пары, показывающие исключение (см. листинг 5).
Листинг 5. Создание JSON-фида для исключения
public Object produceExceptionFeed(Exception ex, PrintWriter writer, String id) {
// TODO Auto-generated method stub
JSONHandler json = null;
try {
json = this.getJSONHandler(writer);
json.startDocument();
json.startJSONObject();
json.pair("id", PlaceStatisticsConstants.FEEDNAME);
json.pair("name", PlaceStatisticsConstants.JSONERRORID);
json.pair("message", ex.getMessage());
json.endJSONObject();
json.endDocument();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
|
Не следует забывать, что сервлету нужны подробные сведения о текущем пользователе. А чтобы работать с этими сведениями, сервлет должен быть защищен. Незащищенный сервлет не способен получать доступ к подробным сведениям о текущем пользователе.
Файл web.xml для сервлета содержит элемент <security-constraint>, задающий ограничение безопасности, HTTP-методы, к которым применяется это ограничение, и роли, которые используют это ограничение. Пример показан в листинге 6.
Листинг 6. Защита сервлета в файле web.xml
<security-constraint id="SecurityConstraint_1">
<web-resource-collection id="WebResourceCollection_1">
<web-resource-name>Statistics Vault</web-resource-name>
<url-pattern>/placestatistics</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint id="AuthConstraint_1">
<description>only for authenticated</description>
<role-name>Authenticated</role-name>
</auth-constraint>
</security-constraint>
<security-role id="SecurityRole_1">
<description>All authenticated users</description>
<role-name>Authenticated</role-name>
</security-role>
|
Наиболее интересные части раздела <security-constraint>/<web-resource-collection> показаны в таблице 3.
Таблица 3. Ограничения безопасности
| Элемент | Описание |
|---|---|
| <url-pattern> | URL-адрес, к которому применяется данное ограничение безопасности. |
| <http-method> | HTTP-методы, к которым применяется данное ограничение безопасности. Если этот элемент оставлен пустым, данное ограничение безопасности применяется ко всем HTTP-методам. Поскольку сервлет PlaceStatistics использует только метод GET, мы применяем ограничение безопасности к операциям GET. |
Следующий шаг состоит в связывании с ролями безопасности, имеющими доступ к данному ресурсу. Это связывание осуществляется с помощью раздела <auth-constraint>. Затем мы должны присвоить определенным пользователям и группам роли, которые мы определили на этапе развертывания приложения. EAR-файл выполняет эту задачу с помощью XML-контента, содержащегося в файлах application.xml и ibm-application-bnd.xml.
EAR-файл определяется файлом application.xml, содержащим сведения о WAR-файлах, подлежащих включению. Кроме того, в нем задаются: корень контекста приложения, например, /lotus/PA_Place_Statistics, и подробности о ролях безопасности, используемых в приложении. Файл ibm-application-bnd.xml связывает роль безопасности с соответствующими пользователями или группами; в данном случае со специальной группой All Authenticated Users.
Оба эти файла содержатся в высокоуровневом каталоге META-INF в EAR-файле, который прилагается к этой статье. Теперь сервлет защищен и ему доступны сведения о текущем пользователе, вошедшем в систему.
С целью максимально полного использования сервлета Place Statistics необходимо предусмотреть средства для выполнения следующих действий:
- Просмотр текущей статистики для места с помощью интерфейса пользователя
- Загрузка CSV-файла, содержащего информацию статистики для места
Такая загрузка может быть выполнена с помощью JavaScript-виджета, разработанного с помощью библиотеки Dojo 1.3.2, которая интегрирована в тему Lotus Quickr. Этот виджет развертывается как часть EAR-файла, прилагаемого к этой статье, и помещается в следующий каталог:
wp_profile/installedApps/<node>/PA_Place_Statistics/js
При извлечении данных для интерфейса пользователя и загружаемого CSV-файла используются разные методы. Интерфейс пользователя может использовать прямой вызов Ajax, а доступ к загружаемому файлу осуществляется с помощью тега <a>.
Создание интерфейс пользователя виджета
Версия виджета с интерфейсом пользователя создается в два этапа. Первый этап состоит в получении доступа к данным посредством использования Ajax-вызова к сервлету Place Statistics. На втором этапе эти данные динамически отображаются в виде простого интерфейса пользователя.
Для извлечения данных используется функция getCurrentStats (), как показано в Листинге 7.
Листинг 7. JavaScript-функция для получения фида статистических данных
getCurrentStats: function() {
var self = this;
var content = {"appid": this.placeId, "format": "json"};
dojo.xhrGet({url: self.serverRoot + "/PA_Place_Statistics/placestatistics",
content: content,
handleAs: "json",
load: function(response) { self._displayStats(response); },
error: function(response,ioargs) {self._displayError(ioargs.xhr.status); }
});
},
|
Идентификатор места, для которого мы хотим получить статистику, хранится как атрибут виджета. Устанавливается JavaScript-объект, содержащий «контент» запроса. Этот контент состоит из идентификатора места placeId и индикатора, показывающего, что мы желаем возвращения именно JSON-структуры.
После этого осуществляется запрос к сервлету Place Statistics. По мере необходимости выполняются обратные вызовы, сцепленные с обработчиками загрузки или ошибок.
В случае успеха этого вызова осуществляется вызов функции _displayStats(). На этом шаге массив элементов, объявленный в JSON, используется для динамического построения HTML-таблицы, содержащей статистические данные. Пример показан в листинге 8.
Листинг 8. Пример JavaScript-кода для отображения статистики
_displayStats: function(json) {
dojo.byId(this.id + "_loading").style.display="none";
// Go through each of the items. Each item represents a set of statistics.
var self = this;
var rangeString = this._labels["rangestring"] + " " +
json.fromDate + " - " + json.toDate;
var statsHolder = dojo.create("div", {id: this.id + "_statsHolder", style:
{height: "260px", "overflow": "auto"}},
dojo.byId(this.id + "_statsdisplay"));
dojo.create("h3",{},statsHolder).innerHTML = rangeString;
// Start a table.
var statTable = dojo.create("table",
{className: "lotusTable", border: "0", cellspacing: "0",
cellpadding: "0"}, statsHolder);
if (json.items.length > 0) {
var statsData = json.items[0].statistics;
// Go through each of the statistics and create a row on the table.
dojo.forEach(statsData, function(stat) {
var newRow = statTable.insertRow(0);
var statDescCell = newRow.insertCell(0);
statDescCell.innerHTML = self._labels[stat.key];
var statValueCell = newRow.insertCell(1);
statValueCell.innerHTML = stat.value;
});
}
},
|
Создание загружаемого CSV-файла
Виджет Place Statistics также предоставляет ссылку для получения всей статистики о месте в виде загружаемого файла в формате CSV. Эта ссылка формируется при открытии диалогового окна; обычная ссылка PlaceStatistics используется с параметрами, показанными в таблице 4.
Таблица 4. Параметры запроса для получения загружаемого CSV-файла
| Параметры URL-адреса | Описание/содержание |
|---|---|
| appid | Идентификатор приложения |
| format | “csv” |
| fromDate | Первое данное, для которого доступны статистические данные |
| toDate | Последнее данное, для которого доступны статистические данные |
Сведения о начальной и конечной дате получаются из JSON-структуры, возвращенной в качестве ответа на вызов xhrGet в функции _getCurrentStats (). Поскольку доступ к URL осуществляется нажатием на ссылку (а не с помощью вызова xhrGet), необходимо написать код для каждого параметра. В ответе от сервлета параметр content-type имеет значение application/x-download, поэтому браузер отображает окно Open/Save.
Мы собираемся реализовать следующую возможность: если доступ к виджету Place Statistics осуществляется посредством ссылки, он представляется в виде окна. Этот доступ реализуется посредством оформления виджета в виде окна с последующим включением функций для отображения и свертывания виджета, представленного как окно.
Сначала можно рассмотреть элементы стиля, которые определяют отображение окна. На этом шаге мы включаем в виджет охватывающий тег <div> и назначаем ему класс lotusDialogBorder со следующими атрибутами: max-width и width. Кроме того, в нем должен находиться элемент формы с классами lotusDialog и lotusForm.
В листинге 9 показан фрагмент HTML-кода, иллюстрирующий требуемую разметку окна.
Листинг 9. HTML-код для окна виджета
<div class="lotusDialogBorder" style="max-width:600px; width:600px;">
<form id="${id}_PlaceStatsForm"
class="lotusDialog lotusForm" action="javascript:;">
<h1>
<a href="javascript:;"
class="lotusBtnImg lotusClose" title="Close Dialog"
dojoAttachEvent="onclick: closeStatistics">"
<img src="${commonRes}/css/images/blank.gif"/>
</a>Place Statistics
</h1>"
<div class="lotusDialogContent">
<div>
Main part of widget markup goes in here.
</div>
</div>
<div class="lotusDialogFooter">
<input value="Close" class="lotusFormButton"
dojoAttachEvent="onclick: closeStatistics"/>
</form>
</div>
|
При нажатии на ссылку Place Statistics на экране отображается окно. Это окно должно предоставлять способ для своего закрытия. Эта задача решается с помощью функции closeStatistics(), связанной с кнопками close посредством деклараций dojoAttachEvent (см. листинг 9). Функция show предназначена для динамического создания Dojo-объекта window (окно) и помещения в него контента PlaceStatistics (см. листинг 10).
Листинг 10. JavaScript-функция для отображения окна
….
popup: null,
postMixInProperties: function() {
this.popup = new dijit.Dialog({});
}, …...
show: function() {
this.popup.attr("content",this.domNode);
this.popup.show();
this.getCurrentStats();
},
|
Функция postMixInProperties создает пустое окно. Затем функция show помещает в окно верхний DOM-узел виджета (this.domNode), отображает его и, наконец, получает статистику места.
Функция closeStatistics еще проще — она вызывает метод hide (скрыть) для данного окна, что приводит к прекращению его отображения.
closeStatistics: function()
this.popup.hide();
}
Итак, мы создали сервлет и написали программный код для поддержки аутентификации, выходных типов и т.д. Кроме того, был написан программный код Dojo-виджета, который используется для отображения статистических сведений пользователю. Теперь необходимо развернуть этот код на сервере и добавить элементы в тему, чтобы сделать новую опцию доступной.
В следующих разделах полностью описывается процесс установки, а также все изменения, которые необходимо внести в тему.
Установка сервлета и виджета с помощью EAR-файла
EAR-файл, прилагаемый к данной статье, содержит сервлет и Dojo-виджет, которые служат для формирования интерфейса пользователя к данным Place Statistics. Этот EAR-файл может быть установлен на сервер Lotus Quickr с помощью консоли администрирования продукта WebSphere Application Server. Установка EAR-файла помещает приложение в корень контекста /lotus/PA_Place_Statistics (заданный в файле application.xml). После того как EAR-файл будет импортирован, должно быть запущено приложение – только после этого можно будет использовать сервлет или Dojo-виджет.
Посмотрите в каталог <server_root>\wp_profile\installedApps\<node>, вы увидите там каталог PA_Place_Statistics.
Теперь нам остается лишь внести в тему определенные изменения, которые позволят пользователю отображать наш виджет. Мы собираемся включить виджет в среду Lotus Quickr таким образом, чтобы к нему можно было бы обращаться с помощью ссылки на боковой навигационной панели для места (см. рис. 2).
Рис. 2. Боковая навигационная панель с новой ссылкой Place Statistics
Необходимо выполнить следующие задачи.
- Обновить файл sideNav.jspf для предоставления доступа к виджету
- Обновить файл js.jsp для загрузки Dojo-виджета
Оба файла, которые мы собираемся изменить, содержатся в приложении:
<server_root>\wp_profile\installedApps\<node>\QuickrThemeApp.ear
Эти же файлы по отдельности содержатся в следующем каталоге.
wp.theme.quickrtheme.war\themes\html\Quickr\js\js.jsp
wp.theme.quickrtheme.war\themes\html\Quickr\sideNav.jspf
Прежде чем мы произведем любое из этих изменений, желательно сохранить копии этих файлов темы.
Загрузка виджета в файл js.jsp
В файл js.jsp необходимо внести изменения, обеспечивающие загрузку виджета Place Statistics из приложения PA_Place_Statistics. Файл js.jsp имеет следующее местонахождение:
installedApps\QuickrThemeApp.ear\wp.theme.quickrtheme.war\themes\html\Quickr\js
Сначала необходимо зарегистрировать путь к модулю, чтобы библиотека Dojo знала, где получить инструмент для просмотра статистики. В файле js.jsp уже есть несколько операторов dojo.registerModulePath, поэтому под этими операторами можно добавить следующую строку:
dojo.registerModulePath('com.ibm.quickr.statistics','/lotus/PA_Place_Statistics/js');
Затем в файл js.jsp необходимо добавить строку <c:import> для загрузки виджета Place Statistics. Добавьте следующий код:
<c:import url="/js/PlaceStatisticsViewer.js" context="/lotus/PA_Place_Statistics"/>
Следует отметить, что после помещения этой ссылки в JSP-файл для корректной работы этой темы на сервере должно быть запущено приложение /lotus/PA_Place_Statistics.
Обновите файл sideNav.jspf для получения доступа к виджету
Теперь рассмотрим внесение в файл sideNav.jspf темы изменений, содержащих ссылку для запуска окна PlaceStatistics. Этот файл имеет следующее местонахождение:
installedApps\QuickrThemeApp.ear\wp.theme.quickrtheme.war\themes\html\Quickr\sideNav.jspf.
Необходимы два основных изменения:
- HTML-разметка для отображения ссылки
- Новая JavaScript-функция для открытия виджета
Учебный файл sideNav.jspf, прилагаемый к данной статье, содержит примеры соответствующего кода; эти разделы отмечены комментариями, содержащими текст “PLACESTATS”. Вам следует скопировать эти фрагменты и вставить их в свою копию файла sideNav.jspf, а не заменять копию это файла на вашем сервере файлом из этой статье.
Новая функция для отображения виджета помещается в нижней части скрипта. В эту функцию необходимо передать идентификатор placeId, корень контекста темы и корень ресурса темы, чтобы эти сведения могли быть отосланы в виджет.
Разметка для вывода ссылки в интерфейсе пользователя должна содержать следующее условие: переменная isApplicationManager имеет значение «true». Тогда ссылка будет отображаться только в случае, если текущий пользователь является менеджером. Кроме того, необходим определенный программный код для получения корня контекста темы и корня ресурса темы. Эта задача решается с помощью кода, показанного в листинге 11.
Листинг 11. JSP-компонент для демонстрации ссылки Place Statistics в теме Lotus Quickr
<c:if test="${isApplicationManager}">
<div>
<%
String themeContextRoot = theme.getContextRoot();
String themeResourceRoot = theme.getResourceRoot();
%>
<a href="javascript:;" onclick='showStatistics("<%=cdoGuid%>",
"<%=themeContextRoot%>","<%=themeResourceRoot%>")'>
Place Statistics</a>
</div>
</c:if >
|
Ссылка для доступа к виджету задается элементом <a>. Он содержит обработчик onclick-событий, который вызывает новую функцию для демонстрации виджета и для передачи идентификатора placeID, корня контекста темы и корня ресурса темы.
И, наконец, чтобы изменения темы вступили в силу, необходимо изменить метку даты в файле Default.jsp. Этот файл имеет следующее местонахождение:
installedApps\QuickrThemeApp.ear\wp.theme.quickrtheme.war\themes\html\Quickr\Default.jsp
Один из способов изменения метки времени — открыть файл в текстовом редакторе, внести необходимые изменения и сохранить файл.
После внесения всех описанных изменений, новая ссылка отображается под левым навигационным меню (см. рис. 3).
Рис. 3. Левая навигационная панель с добавленной ссылкой Place Statistics
Нажатие на ссылку Place Statistics приведет к появлению окна, показанного на рис. 4.
Рис. 4. Статистические данные места, показанные в Web-интерфейсе пользователя для менеджеров места
Нажатие на ссылку Download Statistics в нижней части приведет к отображению обычного окна загрузки браузера. По умолчанию загружаемому файлу будет дано имя placestatistics.csv. Этот файл можно сохранить или открыть с помощью любой программы, способной читать CSV-файлы, например, IBM Lotus Symphony™.
Использование загруженных статистических сведений
Теперь, когда владельцы мест имеют механизм для загрузки статистики о своих местах, их будет интересовать вопрос, какие статистические данные им доступны и какие отчеты можно создать.
Владельцы мест могут получить следующие статистические данные уровня места.
- Общее количество элементов контента
- Общий объем элементов контента (КБ)
- Общее количество элементов контента, добавленных сегодня
- Общее количество элементов контента, обновленных сегодня
- Общее количество элементов Web-контента (постов в блогах, wiki-страниц, комментариев)
- Общее количество документов
- Общее количество элементов Web-контента, добавленных сегодня
- Общее количество элементов Web-контента, обновленных сегодня
- Общее количество документов, добавленных сегодня
- Общее количество документов, обновленных сегодня
- Общее количество постов в блогах
- Общее количество wiki-страниц
- Общее количество комментариев
На рис. 5 показан пример загруженной статистики для места в формате CSV.
Рис. 5. Пример статистических сведений в формате CSV
Place level statistic data. Place Name: test1 ,"Total number of contents","Total size of contents (KB)", "Total number of contents added today", ...... 2010-06-25,17443,1666,4640,2653,8896,8547,424,4881,4216,2430,1240,4371,2861 2010-06-26,17865,3198,8101,3065,11472,6393,4334,3291,3767,1663,1673,4977,488 2010-06-27,17529,4311,6957,4239,11471,6058,3002,4720,3955,1499,162,4389,3918 ...... ...... |
Загруженный CSV-файл можно открыть с помощью электронной таблицы (Lotus Symphony, Microsoft Excel или какого-либо другого приложения для работы с электронными таблицами), а затем создавать на основе содержащихся в нем статистических данных диаграммы. На рис. 6 и 7 представлены две таблицы, составленные на основе данных «Общее количество элементов контента» и «Общий объем элементов контента (КБ)» с помощью электронных таблиц Lotus Symphony.
Рис. 6. Пример графика, демонстрирующего количество элементов контента для места
Рис. 7. График, демонстрирующий общий объем элементов контента
CSV-файл, содержащий статистические данные для этих графиков, включен в Приложение 2 данного документа.
В статье демонстрируется использование сервисов Place Statistics, поддерживаемых продуктом Lotus Quickr 8.5, для формирования пользовательского интерфейса, отображающего данные, и для реализации возможности экспорта статистических данных в другие приложения.
Было продемонстрировано создание фидов в различных форматах с помощью Abdera и API-интерфейса WebSphere Portal, а также представлен программный код для чтения этих фидов.
Кроме того, данная статья может служить вводным материалом по включению Dojo-виджетов в тему Lotus Quickr 8.5. Методика построения окна Dojo и его связывания с экземпляром темы может быть использована во многих других ситуациях.
Приложение 1. Пример Atom-фида
<feed xmlns:td="urn:ibm.com/td" xmlns="http://www.w3.org/2005/Atom">
<id>urn:lsid:ibm.com:td:statistics</id>
<title type="text">Lotus Quickr Admin Feed</title>
<link href="/adminqcs/rest/statistics/feed" rel="self"></link>
<link href="/adminqcs/rest/QuickrAdmin" rel="alternate"></link>
<updated>2010-06-09T15:45:25.984Z</updated>
<author>
<name>Quickr Admin</name>
</author>
<td:total xmlns:td="urn:ibm.com/td">1</td:total>
<td:statistic-range xmlns:td="urn:ibm.com/td" from="2010-05-07"
to="2010-06-08"></td:statistic-range>
<entry xmlns:td="urn:ibm.com/td">
<link rel="self"></link>
<link rel="edit"></link>
<id>1F_18M131M418NA60I2JCM5B51021</id>
<title type="text">Place level statistic data. Place Name: Self Join Library</title>
<published>2010-06-07T23:00:00.000Z</published>
<updated>2010-06-07T23:00:00.000Z</updated>
<td:statistics xmlns:td="urn:ibm.com/td">
<td:property xmlns:td="urn:ibm.com/td"
key="document_totalNum">1</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_size">1</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_createdToday">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_modifiedToday">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_webdoc">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_webdocCreatedToday">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_webdocModifiedToday">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_libdoc">1</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_libdocCreatedToday">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_libdocModifiedToday">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_blog_totalNum">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_wiki_totalNum">0</td:property>
<td:property xmlns:td="urn:ibm.com/td"
key="document_comment_totalNum">0</td:property>
</td:statistics>
</entry>
</feed>
|
Приложение 2. CSV-файл для диаграмм
Place level statistic data. Place Name: test1 ,"Total number of contents","Total size of contents (KB)","Total number of contents added today","Total number of contents updated today","Total number of web contents (blog post, wiki page, comment)","Total number of documents","Total number of web contents added today","Total number of web contents updated today","Total number of documents added today","Total number of documents updated today","Total number of blog posts","Total number of wiki pagess","Total number of comments" 2010-06-25,17443,1666,4640,2653,8896,8547,424,4881,4216,2430,1240,4371,2861 2010-06-26,17865,3198,8101,3065,11472,6393,4334,3291,3767,1663,1673,4977,488 2010-06-27,17529,4311,6957,4239,11471,6058,3002,4720,3955,1499,162,4389,3918 2010-06-28,14208,4323,5054,3620,10080,4128,2581,1121,2473,702,4201,746,2552 2010-06-29,12443,1301,3867,981,7597,4846,2371,2501,1496,749,217,2540,2469 2010-06-30,15494,2366,2938,1801,10809,4685,2701,2903,237,4286,4566,3290,252 2010-07-01,16620,4674,6849,627,8317,8303,2249,4931,4600,2813,3562,397,2109 2010-07-02,9927,1950,1054,3002,7314,2613,607,2125,447,4642,145,2428,4134 2010-07-03,8095,2436,3233,4363,3595,4500,1293,2074,1940,3416,93,20,2189 2010-07-04,19311,4066,3796,1185,14135,5176,3450,4040,346,1976,4446,2514,3725 2010-07-05,19913,2261,9272,3160,11316,8597,4403,1798,4869,1574,894,1877,4142 2010-07-06,12321,1792,5029,2556,8998,3323,3262,1967,1767,1133,3963,814,959 2010-07-07,16604,2194,5726,371,12048,4556,2828,4418,2898,1580,2932,2919,3369 2010-07-08,12897,2147,6183,2345,7288,5609,2505,703,3678,2593,2136,668,1979 2010-07-09,12351,3222,5878,38,8290,4061,4402,1953,1476,1439,488,3182,218 2010-07-10,12801,2088,7208,4206,7752,5049,2606,2225,4602,1547,3584,1414,148 |
| Имя | Размер | Метод загрузки |
|---|---|---|
| place.zip | 3.51 MБ | HTTP |
- Примите участие в обсуждении материала на форуме.
-
Оригинал статьи: IBM Lotus Quickr usage statistics: Measuring the success of team collaboration.(EN)
-
Ознакомьтесь с документацией по продукту Lotus Quickr 8.5 for WebSphere Portal documentation.
-
Wiki-ресурс по продукту Lotus Quickr.
-
Информационный центр по продукту WebSphere Portal V6.1.5.
-
Web-сайт Dojo Campus содержит множество примеров по Dojo.
-
Дополнительная информация по Dojo Toolkit, в т.ч. документация и примеры.
-
Дополнительная информация по проекту Apache Abdera Project.
Джим Антилл (Jim Antill) — разработчик программного обеспечения, специализируется на продуктах для социального взаимодействия и группового сотрудничества. Дж. Антилл участвовал в создании выпуска Lotus Quickr 8.5, где занимался преимущественно опцией Member Management. Адрес электронной почты: ANTILLJI@ie.ibm.com.
Нэн Ши (Nan Shi) — инженер-консультант по программному обеспечению, специализируется на продуктах для социального взаимодействия и группового сотрудничества. Более 10 лет проработала консультантом по ИТ-решениям и по разработке программного обеспечения. Участвовала в создании компонента Lotus Quickr Admin Console (в качестве технического руководителя) и продукта Lotus Quickr 8.5 (в качестве разработчика). Адрес электронной почты: nanshi@cn.ibm.com.
Джон Брунн (Jon Brunn) — старший инженер по программному обеспечению, специализируется на продуктах для социального взаимодействия и группового сотрудничества. Дж. Брунн более 10 лет занимается системами управления контентом, включая IBM Content Manager и FileNet P8. Он участвовал в разработке следующих продуктов: Lotus Quickr, Lotus Connections, WebSphere Portal, Web Content Management, FileNet и IBM Content Manager. Адрес электронной почты: jbrunn@us.ibm.com.