Получение статистики использования с помощью IBM Lotus Quickr: Измерение успешности сотрудничества в группе

Продукт IBM® Lotus® Quickr® 8.5 for IBM WebSphere® Portal представляет статистические данные на уровне сервера и на уровне мест. Администраторы могут вести мониторинг использования системы через административный Web-интерфейс. Кроме того, можно получать статистику для мест Lotus Quickr посредством вызова REST-сервисов в корне контекста \adminqcs. Эти сервисы предоставляют статистические сведения как для сервера, так и для конкретных мест.

Джимм Антилл, разработчик программного обеспечения, IBM

Джим Антилл (Jim Antill) — разработчик программного обеспечения, специализируется на продуктах для социального взаимодействия и группового сотрудничества. Дж. Антилл участвовал в создании выпуска Lotus Quickr 8.5, где занимался преимущественно опцией Member Management. Адрес электронной почты: ANTILLJI@ie.ibm.com.



Нэн Ши, инженер-консультант по программному обеспечению, IBM

Нэн Ши (Nan Shi) — инженер-консультант по программному обеспечению, специализируется на продуктах для социального взаимодействия и группового сотрудничества. Более 10 лет проработала консультантом по ИТ-решениям и по разработке программного обеспечения. Участвовала в создании компонента Lotus Quickr Admin Console (в качестве технического руководителя) и продукта Lotus Quickr 8.5 (в качестве разработчика). Адрес электронной почты: nanshi@cn.ibm.com.



Джон Брунн, старший инженер по программному обеспечению, IBM

Джон Брунн (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.



09.12.2011

Примечание редактора: Обладаете глубокими знаниями по данной теме? Хотите поделиться своей компетентностью? Примите участие в Wiki-программе по продуктам IBM Lotus.

Введение

Статистические данные по отдельным местам (place) содержат полезную информацию о местах, включая количество документов в конкретном месте, количество измененных сегодня документов, количество документов в библиотеке и т.д. Эта информация полезна для владельцев мест и для администратора сервера. Кроме того, эту статистику можно просматривать с помощью простого пользовательского интерфейса, доступного из темы, а также загружать в формате CSV, который импортировать в электронную таблицу.

В этой статье мы сделаем эти статистические данные более удобными для использования владельцами мест. Мы собираемся сделать следующее:

  • Разработать сервлет для получения доступа к фидам Place Statistics
  • Применить Abdera для вызова adminqcs-фидов, для построения Atom-фидов и для разбора XML
  • Использовать API-интерфейс WebSphere Portal для связывания фидов JSON
  • Защитить новый сервлет
  • Написать Dojo-виджет, который будет поддерживать простой интерфейс пользователя и предоставлять средства для загрузки CSV-файла
  • Интегрировать этот виджет с темой Lotus Quickr

Полученный в итоге интерфейс пользователя в удобной форме демонстрирует владельцам мест статистику о контенте, о росте и о «здоровье» соответствующего места.

Все необходимые материалы для развертывания виджета Place Statistics содержатся в EAR-файле, приложенном к этой статье. В разделе «Развертывание» описывается, как установить этот виджет и как внести в тему изменения, позволяющие получить доступ к новой функции.


Сервлет Place Statistics

Начнем с построения сервлета для получения статистических данных о месте. Этот сервлет использует существующий фид \adminqcs, добавляя к нему возможности для вывода сведений в формате JSON. Вывод в формате JSON упрощает использование JavaScript-компонентов в выходном фиде.

На рис. 1 показано, как взаимодействуют компоненты сервлета. После поступления запроса выполняется получение данных из фида \adminqcs в формате Atom или в формате CSV в зависимости от необходимого конечного формата. Извлечение данных осуществляется с помощью компонента FeedRetriever. Затем эти данные передаются в компонент FeedHandler, который обеспечивает вывод статистических данных в надлежащем формате. К примеру, если нам нужен формат JSON, мы получаем вывод в формате JSON, а не в формате Atom или CSV.

Рис. 1. Сервлет Place Statistics
Place Statistics servlet

Авторизация

Статистические данные места могут быть получены любым лицом с ролью менеджера этого места или любым лицом с ролью, имеющей полномочия 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.

Получение Atom-фида

Класс 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-фида

Получение 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

AtomFeedHandler выводит фид Place Statistics в формате Atom. Нам достаточно взять Atom-фид, полученный от сервиса \adminqcs, и передать его наружу с помощью ответа для сервлета.

JSONFeedHandler

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

С целью максимально полного использования сервлета 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>

Добавление функций show/hide

При нажатии на ссылку 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
Side navigation showing new Place Statistics link

Необходимо выполнить следующие задачи.

  • Обновить файл 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
Left navigation with Place Statistics added

Нажатие на ссылку Place Statistics приведет к появлению окна, показанного на рис. 4.

Рис. 4. Статистические данные места, показанные в Web-интерфейсе пользователя для менеджеров места
Place Statistics displayed in the web user interface to place managers

Нажатие на ссылку 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. Пример графика, демонстрирующего количество элементов контента для места
Example graph showing number of contents for places
Рис. 7. График, демонстрирующий общий объем элементов контента
Graph showing total size of contents

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.zip3.51 MБ

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Lotus
ArticleID=780147
ArticleTitle=Получение статистики использования с помощью IBM Lotus Quickr: Измерение успешности сотрудничества в группе
publish-date=12092011