Estatísticas de uso do IBM Lotus Quickr: Medindo o Sucesso da Colaboração em Equipe

O IBM® Lotus® Quickr® 8.5 para IBM WebSphere® Portal apresenta estatísticas em termos de servidor e local. Os administradores podem monitorar o uso do sistema por meio de uma interface administrativa com o usuário da Web. As estatísticas referentes a locais do Lotus Quickr também podem ser obtidas chamando serviços REST na raiz de contexto \adminqcs. Esses serviços fornecem estatísticas referentes a todo o servidor e também estatísticas específicas de local.

Jim Antill, Software Developer, IBM

Jim Antill photoJim Antill é desenvolvedor de software e trabalha com softwares sociais e de colaboração em equipe. Jim contribuiu para o release do Lotus Quickr 8.5, trabalhando principalmente nos aspectos de gerenciamento de membros do produto. É possível entrar em contato com ele pelo e-mail ANTILLJI@ie.ibm.com.



Nan Shi, Advisory Software Engineer, IBM

Nan Shi é engenheira consultora de software e trabalha com softwares sociais e de colaboração em equipe. Nan tem mais de 10 anos de experiência em consultoria de soluções de TI e desenvolvimento de software. Ela contribuiu para o componente Lotus Quickr Admin Console como líder técnica e desenvolvedora do Lotus Quickr 8.5. É possível entrar em contato com ela pelo e-mail nanshi@cn.ibm.com.



Jon Brunn, Senior Software Engineer, IBM

Jon BrunnJon Brunn é o arquiteto do Lotus Quickr para a integração do Enterprise Content Management. Atualmente, Jon contribui com o produto Lotus Quickr, principalmente nas áreas de extensão, customização e integração corporativa. É possível entrar em contato com Jon pelo e-mail jbrunn@us.ibm.com.



06/Dez/2010

Nota do editor: Possui muito conhecimento sobre este tópico? Deseja compartilhá-lo? Participe do programa de wiki do software IBM Lotus hoje mesmo.

Introdução

As estatísticas específicas de local oferecem informações úteis sobre um local, como o número de documentos no local, o número de documentos modificados no dia atual, o número de documentos de biblioteca, etc. Essas informações são úteis para os proprietários de locais e para o administrador do servidor. As estatísticas também devem ser vistas por meio de uma interface com o usuário (UI) simples que é acessível a partir do tema e também existe em um formato CSV que pode ser transferido por download e importado para uma planilha.

Neste artigo, você torna essas estatísticas mais "consumíveis" para os proprietários de locais. Você fará o seguinte:

  • Desenvolverá um servlet para acessar feeds do Place Statistics
  • Usará o Abdera para chamar os feeds de adminqcs, construir feeds Atom e analisar o XML
  • Usará a API do WebSphere Portal para preparar feeds de JSON
  • Protegerá o novo servlet
  • Escreverá um widget em Dojo para fornecer uma UI simples e um meio de fazer o download do arquivo CSV
  • Integrará o widget ao tema do Lotus Quickr

A UI resultante mostra estatísticas sobre conteúdo, crescimento e funcionamento do local aos proprietários do local em uma forma consumível.

Todos os materiais necessários para implementar o widget Place Statistics estão contidos no arquivo EAR fornecido neste artigo. A seção “Implementação” deste artigo descreve como instalar esse widget e alterar o tema para que o novo recurso possa ser acessado.


Servlet Place Statistics

Vamos começar construindo o servlet para obter os dados estatísticos do local. O servlet usa o feed \adminqcs já existente, acrescentando a capacidade de fazer a saída dos detalhes no formato JSON. O fato de ter uma saída com o formato JSON facilita a utilização da saída de feed pelos componentes do JavaScript.

A Figura 1 mostra como as partes que formam o servlet funcionam em conjunto. Uma solicitação entra e os dados do feed \adminqcs são obtidos no formato Atom ou CSV, dependendo do formato que será necessário em última análise, usando o FeedRetriever. Em seguida, os dados são passados para o FeedHandler, que faz com que a saída dos dados estatísticos tenha o formato correto; portanto, se queremos o formato JSON, sairá JSON e não Atom ou CSV.

Figura 1. Servlet do Place Statistics
Servlet do Place Statistics

Autorização

Os dados estatísticos do local podem ser obtidos por qualquer pessoa que tenha função gerencial referente ao local ou qualquer pessoa que tenha uma função com permissão de Manage Membership.

Nenhuma autorização extra é fornecida pelo servlet do Place Statistics descrito neste artigo. A classe PlaceStatisticsRetriever no código de exemplo contém um método authenticateAccess() que pode ser usado para realizar autorizações adicionais. Se o método é implementado, ele lança uma PlaceStatisticsAuthenticationException caso o usuário atual não tenha permissão para visualizar as estatísticas. O método authenticateAccess() é chamado antes da obtenção das estatísticas do local.


Recuperador de feeds: consumindo o feed do Place Statistics

O feed \adminqcs já existente do Place Statistics fornece detalhes no formato Atom ou CSV. O formato Atom é fácil de analisar usando o código Java e fornece uma visualização estruturada das estatísticas do local. O feed em CSV fornece um feed que pode ser transferido por download para um arquivo a partir do navegador, mas é difícil de tratar para qualquer outro propósito.

É necessário um código diferente para recuperar cada uma desses feeds, porque são apresentados em formatos diferentes — o CSV está em um fluxo e o Atom está em um documento XML. O comportamento de que você precisa é o comum, para que possa ser expresso por meio de uma interface que cada recuperador de feed criado por você possa implementar. Essa interface é descrita na Listagem 1.

Listagem 1. Interface #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; }

O método getFeed() toma como entrada a URL cujo feed você quer obter (incluindo parâmetros como datas de/para) e os cookies necessários para a autenticação; o serviço \adminqcs usa os tokens de LTPA (cookies) que o WebSphere Portal usa para a autenticação.

As classes são criadas estendendo essa interface, que fornece a sua própria implementação do método getFeed(). Para garantir o uso da implementação correta de leitor de feed, você também cria uma classe factory que fornece o leitor de feed adequado com base no formato de saída final desejado. No caso em que a saída necessária é CSV, é usado o CSVFeedRetriever. Em todos os outros casos, o AtomFeedRetriever é usado porque o documento de Atom produzido pode, em seguida, ser analisado de outras formas, como JSON.

Se outros tipos de saída do serviço \adminqcs ficam disponíveis, é possível criar uma classe para tratar esse tipo de feed sem afetar as classes que tratam os feeds Atom e CSV.

Obtendo o feed Atom

A classe AtomFeedRetriever é usada para recuperar a versão em Atom do feed do Place Statistics.

O Apache Abdera é usado para fazer a solicitação de HTTP ao serviço \adminqcs. O Abdera também é usado para tratar os dados retornados e mais algumas coisas no projeto. Uma instância da classe AbderaClient e uma instância da classe RequestOptions — que é usada para passar opções como cookies na solicitação — são necessárias.

Um dos parâmetros do método getFeed é um array de cookies. Alguns dos cookies na solicitação do servlet original são os cookies LTPA que o WebSphere Portal usa para a autenticação. Uma instância da classe org.apache.abdera.protocol.client.RequestOptions é criada e os detalhes dos cookies são configurados. Os cookies devem ser definidos como um array de cadeias de caracteres, uma para cada cookie, com cada cadeia de caractere tendo a seguinte forma:

nome = valor

Você repassa os cookies, forma uma matriz de sequência com um elemento para cada cookie e, em seguida, usa essa matriz para configurar o objeto RequestOptions como se mostra na Listagem 2.

Listagem 2. Configurando cookies para solicitação
 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()]));

A solicitação propriamente dita é feita usando o método get() na instância AbderaClient, passando a URL da solicitação e o objeto RequestOptions que você configurou. A resposta é uma instância da classe ClientResponse do Abdera que contém detalhes do status da resposta (por exemplo: sucesso ou falha) e os dados enviados na resposta. Nessa instância, pressupondo uma resposta bem-sucedida, a resposta contém o documento XML do Atom. Esse documento pode ser extraído usando o método getResponse() na instância de ClientReponse. Em caso de falha, uma exceção é levantada e tratada.

A resposta obtida é enviada como a saída do recuperador de feed, pronta para ser usada em outro lugar.

Obtendo o feed de CSV

A obtenção do feed em CSV é semelhante à obtenção do feed do Atom Place Statistics; a única diferença real é a forma de tratar a saída da solicitação.

Como antes, é necessário definir os cookies em uma tentativa de configurar o objeto RequestOptions e, em seguida, enviar a solicitação.

Dessa vez, você obtém um feed em CSV retornada na forma de uma InputStream, que deve ser lida. Uma boa opção é usar um BufferedReader para ler um bit do fluxo por vez. Cada bit lido é anexado a um objeto StringBuffer até que não haja nada mais para ler. Nesse ponto, é possível retornar o StringBuffer como a saída do recuperador.


Realizando a saída no formato necessário

Agora que você está com os dados do Place Statistics no formato Atom ou CSV, é necessário formar a saída que é enviada ao responsável pela chamada do seu servlet na forma em que foi pedida originalmente.

Para manter as coisas organizadas e flexíveis, é possível usar uma classe separada para tratar cada formato de saída, e cada uma delas fornece a funcionalidade listada na Tabela 1.

Tabela 1. Funções de saída das classes dos dados estatísticos
Função de saídaDescrição detalhada
Tratar o feed de estatísticasTomar o feed de estatísticas e gravá-lo no formato necessário, no fluxo de saída determinado.
Fornecer o tipo de conteúdoFornecer um meio de recuperar o tipo de conteúdo do formato de saída. Depois de criar uma instância de FeedHandler, o tipo de conteúdo do feed pode ser obtido por meio desse método.
Gravar a saída da exceçãoRealizar a saída dos detalhes de uma exceção no formato determinado. Por exemplo: se ocorre uma exceção no processamento do AtomHandler, ele grava os detalhes da exceção em um formato Atom.

Já que as operações oferecidas pelas classes são as mesmas, é possível usar uma interface para definir um contrato que todas as suas classes implementam. Um exemplo disso é mostrado na interface BaseFeedHandler, na Listagem 3.

Listagem 3. Interface 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();
    }

O tipo de feed que é passado ao método handleStatsFeed depende do tipo de feed da saída. Por exemplo: se você está tratando um feed Atom, o parâmetro de feed é uma feed Abdera, mas é um StringBuffer se você está tratando um feed em CSV.

AtomFeedHandler

O AtomFeedHandler faz a saída do the Place Statistics no formato Atom. Basta tomar o feed Atom recuperado do serviço \adminqcs e passá-lo usando a resposta para o servlet.

JSONFeedHandler

O JSONFeedHandler faz a saída do feed do Place Statistics em um formato JSON e requer um pouco mais de trabalho. O feed esperado pela função é o feed Atom produzido pelo serviço adminqcs.

O manipulador faz a saída de uma estrutura JSON capaz de descrever o feed de estatísticas referente a um local; este é um exemplo:

{id : "statistics", fromDate : "2010-05-27", toDate : "2010-05-30",
title: "Lotus Quickr Admin Feed", items: [{"published", statistics:
[{key: "document_totalNum", value: 1}]}]}

A primeira parte do feed contém o ID do feed, as datas de/a referentes ao feed e o título do feed. Depois, vem o array de itens, e um item do array corresponde a um único elemento <entry> no feed Atom.

Cada item tem uma data de publicação, um título e um array. Esse array final contém as informações estatísticas referentes ao local, e cada item tem uma chave e um valor. A chave identifica qual é a estatística; por exemplo: document_size, e o valor indica o valor dessa estatística específica.

Usa-se o Abdera para analisar o feed Atom porque ele oferece tudo o que é necessário para analisar um DOM, ou diretamente ou usando consultas Xpath. Conforme você analisa, pode construir a sua estrutura JSON usando as APIs do WebSphere Portal que tratam os caracteres especiais e problemas de codificação, diminuindo um pouco as suas preocupações.

O Apêndice 1 deste artigo mostra um feed Atom padrão referente às estatísticas de local. Com o Abdera, analisar esse feed no formato JSON é fácil.

A lista de entradas no feed Atom é obtida primeiro; em seguida, é realizada uma procura nessas entradas pelo elemento <statistics> que contém as informações do Place Statistics. Depois que esse elemento é localizado, os elementos dentro dessa entrada sofrem iteração, com pares de JSON sendo formados para cada estatística.

Uma instância da classe JSONHandler é criada e vários métodos dessa instância são usados para construir a estrutura JSON. A Tabela 2 fornece detalhes sobre esses métodos.

Tabela 2. Métodos de manipulação de JSON fornecidos pelo JSONHandler
Método da APIDescrição
startJsonObjectInicia um objeto JSON. É equivalente a digitar uma chave de abertura ({) na estrutura.
jsonPair(chave, principal)Insere um par de chave/valor na estrutura:
fromDate : “2010-05-27”
startArray()Inicia um array na estrutura. É equivalente a digitar um colchete de abertura ([).
startPair(pairkey)Inicia um par de JSON, com a chave sendo passada.
endPair()Termina um par iniciado anteriormente com o método startPair.
endArray()Termina um array iniciado com o método startArray. Insere efetivamente o colchete de fechamento (]) na estrutura.
endJsonObjectTermina um objeto JSON iniciado com o método startJsonObject. Insere efetivamente a chave de fechamento (}) na estrutura.

Produzindo feeds de exceção

Às vezes, as coisas dão errado e o usuário precisa obter informações sobre os erros.

Cada um dos FeedHandlers deve ser capaz de enviar detalhes das exceções que ocorreram, em um formato adequado. Por exemplo: O FeedHandler de Atom envia um documento Atom que contém detalhes do erro, o FeedHandler de JSON envia um documento JSON, etc. Se você não fizer isso, é possível que o xhrGet de manipulação de JSON usado para obter o feed do Place Statistics receba um relatório de exceções de Atom e não saiba o que fazer com ele.

O AtomFeedHandler usa o Abdera para construir um feed Atom que contém detalhes da exceção. É usada uma instância da classe FOMFactory para gerar um novo feed, com detalhes da exceção sendo adicionados a essa instância. Finalmente, a coisa toda é enviada de volta ao responsável pela chamada. É mostrado um exemplo na listagem para produzir um feed Atom referente a uma exceção.

Listagem 4. Código de exemplo para produzir um feed Atom referente a uma exceção
 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; }

O JSONFeedHandler faz a saída das informações sobre a exceção no formato JSON. Os objetos de API do WebSphere Portal usados para formar a saída em JSON (que você viu antes) são usados para formar a nova estrutura. É usada uma instância do com.ibm.portal.streaming.json.JSONHandler para criar um documento no qual os pares em JSON são incluídos, como mostra a listagem 5.

Listagem 5. Produzindo um feed em JSON referente a uma exceção
 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; }

Protegendo o servlet

Lembre-se de que o servlet precisa de detalhes do usuário atual. E, para trabalhar com esses detalhes, o servlet deve ser protegido. Um servlet desprotegido não pode ter acesso aos detalhes do usuário atual.

O arquivo web.xml referente ao servlet contém um elemento <security-constraint> que define a restrição de segurança, os métodos de HTTP aos quais a restrição se aplica e as funções que usam a restrição. A Listagem 6 mostra um exemplo.

Listagem 6. Protegendo o servlet em 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>

Em relação à seção<security-constraint>/<web-resource-collection>, as partes interessantes são mostradas na tabela 3.

Tabela 3. Elementos da restrição de segurança
Elemento de restriçãoDescrição
<url-pattern>A URL à qual a segurança se aplica.
<http-method>O método de HTTP ao qual a segurança se aplica. Se esse elemento fica em branco, a segurança é aplicada a todos os métodos de HTTP. Já que o servlet do PlaceStatistics só usa o método GET, você aplica a segurança a todas as operações de GET.

A próxima etapa é vincular as funções de segurança que têm acesso ao recurso; essa vinculação é feita por meio da seção <auth-constraint>. Em seguida, é necessário colocar usuários e grupos específicos nas funções que você definiu durante a implementação do aplicativo. O arquivo EAR é usado para executar essa tarefa usando o XML contido no arquivo application.xml e nos arquivos ibm-application-bnd.xml.

O arquivo application.xml define o arquivo EAR, detalhando quais arquivos WAR devem ser incluídos. A raiz de contexto do aplicativo (por exemplo: /lotus/PA_Place_Statistics) e detalhes das funções de segurança usadas no aplicativo também são fornecidos. O arquivo ibm-application-bnd.xml liga a função de segurança aos usuários ou grupos adequados; nesse caso, o grupo especial All Authenticated Users.

Esses dois arquivos estão contidos no diretório de nível superior META-INF no arquivo EAR que acompanha este artigo. Agora o servlet está protegido e os detalhes do usuário conectado no momento estão disponíveis a ele.


Widget Place Statistics

Para aproveitar totalmente o servlet Place Statistics, é necessário fornecer um meio de:

  • Visualizar estatísticas atuais de um local usando uma UI
  • Fazer o download de um arquivo CSV que contém as informações do Place Statistics

Pode-se fazer esse download usando um widget em JavaScript desenvolvido usando o Dojo 1.3.2, que está integrado ao tema do Lotus Quickr. Esse widget é implementado como parte do arquivo EAR fornecido neste artigo e é colocado no diretório:

wp_profile/installedApps/<node>/PA_Place_Statistics/js

Obtendo dados

As técnicas usadas para recuperar dados para a UI e para o arquivo CSV que pode ser transferido por download são diferentes — a UI pode usar uma chamada direta de Ajax, mas o arquivo é acessado por meio de uma tag âncora <a>.

Produzindo a UI do widget

A produção da versão do widget com UI é um processo de duas etapas. A etapa 1 é obter os dados usando uma chamada de Ajax para o servlet do Place Statistics. A segunda etapa é tomar os dados e renderizar dinamicamente uma UI simples a partir deles.

A função getCurrentStats() é usada para recuperar os dados, como mostra a Listagem 7.

Listagem 7. Função em JavaScript para obter o feed de estatísticas
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); } }); },

O ID do local cujas estatísticas você quer é mantido como um atributo no widget. Um objeto JavaScript que contém o "conteúdo" da solicitação é configurado; o conteúdo é o placeId e um indicador para informar que você quer que uma estrutura JSON seja retornada.

Em seguida, a solicitação para o servlet do Place Statistics é feita e os retornos de chamada são ligados à carga ou então os manipuladores de erros são chamados, conforme o for adequado.

Supondo-se que a chamada seja bem-sucedida, a função displayStats() é chamada. Essa etapa toma o array de itens declarado no JSON e o usa para construir dinamicamente uma tabela HTML que mostra os detalhes das estatísticas. A Listagem 8 mostra um exemplo.

Listagem 8. Exemplo de código em JavaScript para exibir estatísticas
 _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; }); } },

Produzindo o CSV que pode ser transferido por download

O widget Place Statistics também fornece um link para obter todas as estatísticas de um local em um arquivo que pode ser transferido por download, fornecido no formato CSV. O link é construído quando o diálogo é aberto; o link usual do PlaceStatistics é usado com os parâmetros mostrados na tabela 4.

Tabela 4. Parâmetros de solicitação para obter o download do CSV
Parâmetro de URLDescrição/conteúdo
appidID do aplicativo
formato“csv”
fromDatePrimeira data que tem estatísticas disponíveis
toDateÚltima data que tem estatísticas disponíveis

As datas iniciais e finais são obtidas a partir da estrutura JSON retornada como reposta para a chamada de xhrGet na função _getCurrentStats(). Já que a URL é acessada clicando no link (e não por meio de uma chamada de xhrGet), tome cuidado ao codificar cada um dos parâmetros. A resposta do servlet tem o content-type definido como application/x-download, para que o navegador mostre a janela Open/Save.


Renderizando o widget como uma janela

O Place Statistics será apresentado como uma janela quando for acessado por meio de um link. Esse acesso é feito apresentando o widget como uma janela e, em seguida, incluir funções para mostrar e ocultar o widget encapsulado em uma janela.

Primeiro, é possível examinar a estilização, que afeta a forma de exibição da janela. Essa etapa envolve colocar um <div> de agrupamento ao redor do widget e dar a ele a classe lotusDialogBorder e os atributos max-width e width. Também é necessário ter ali um elemento de formulário, com classes de lotusDialog e lotusForm.

O trecho de código HTML mostrado na listagem 9 ilustra a marcação da janela que é necessária.

Listagem 9. HTML para a janela do widget
 <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>

Incluir as funções de mostrar/ocultar

Quando se clica no link do Place Statistics, a janela é exibida. A janela também precisa fornecer uma forma de se fechar, o que é feito usando a função closeStatistics() ligada aos botões de fechar por meio das declarações de dojoAttachEvent, como mostra a listagem 9. Uma função de exibição deve criar dinamicamente um objeto de janela de Dojo e colocar o conteúdo de PlaceStatistics nele, como mostra a listagem 10.

Listagem 10. Função em JavaScript para mostrar a janela
…. popup: null, postMixInProperties: function() 
{
 this.popup = new dijit.Dialog({}); }, …... show: function() 
{
                this.popup.attr("content",this.domNode);
 this.popup.show(); this.getCurrentStats();
                },

È criada uma janela vazia na função postMixInProperties. Em seguida, a função de exibição coloca o nó superior do DOM do widget (this.domNode) na janela, mostra-o e, finalmente, obtém as estatísticas do local.

A função closeStatistics é ainda mais simples, porque chama o método de ocultar na janela para tirá-la do monitor:

closeStatistics: function()
this.popup.hide();
}


Implementação

Você criou o servlet, codificou cosias para suportar autenticação, tipos de saída, etc. O widget em Dojo usado para exibir as estatísticas ao usuário também foi codificado. Agora é necessário implementá-lo no servidor e incluir itens no tema para deixar o novo recurso acessível.

As seções a seguir descrevem todo o processo de instalação e as mudanças necessárias no tema.

Instalando o servlet e o widget usando o arquivo EAR

O arquivo EAR que acompanha este artigo contém o servlet e o widget em Dojo que é usado para formar uma UI para os dados do Place Statistics. O arquivo EAR pode ser instalado no servidor do Lotus Quickr por meio do console de administração do WebSphere Application Server. A instalação do arquivo EAR coloca o aplicativo na raiz de contexto /lotus/PA_Place_Statistics (definida no arquivo application.xml). Após a importação do EAR, o aplicativo deve ser iniciado para que o servlet ou o widget em Dojo possa ser usado.

Se você olhar no diretório <server_root>\wp_profile\installedApps\<node>, verá o diretório PA_Place_Statistics.

Alterando o tema

Agora, a única coisa que falta fazer é alterar o tema para que o usuário tenha uma forma de exibir do widget. Você incorporará o widget ao Lotus Quickr para que ele possa ser acessado por meio de um link contido na navegação lateral do local, como mostra a figura 2.

Figura 2. Navegação lateral que mostra o novo link do Place Statistics
Navegação lateral que mostra o novo link do Place Statistics

As seguintes tarefas devem ser executadas:

  • Atualizar o sideNav.jspf para fornecer acesso ao widget
  • Atualizar o js.jsp para carregar o widget em Dojo

Os dois arquivos que alteraremos estão contidos no aplicativo:
<server_root>\wp_profile\installedApps\<node>\QuickrThemeApp.ear

E os arquivos individuais sob esse diretório são:
wp.theme.quickrtheme.war\themes\html\Quickr\js\js.jsp
wp.theme.quickrtheme.war\themes\html\Quickr\sideNav.jspf

Antes de fazer essas mudanças, é recomendável salvar cópias desses arquivos do tema.

Carregue o widget no arquivo js.jsp

O arquivo js.jsp file deve ser alterado para carregar o widget Place Statistics a partir do aplicativo PA_Place_Statistics. O arquivo js.jsp está localizado em:
installedApps\QuickrThemeApp.ear\wp.theme.quickrtheme.war\themes\html\Quickr\js

Primeiro é necessário registrar um caminho de módulo para que o Dojo saiba onde obter o visualizador de estatísticas. Já existem várias instruções dojo.registerModulePath no arquivo js.jsp, e a linha a seguir pode ser adicionada abaixo dessas instruções:
dojo.registerModulePath('com.ibm.quickr.statistics','/lotus/PA_Place_Statistics/js');

Em seguida, uma linha <c:import> deve ser incluída no arquivo js.jsp para carregar o widget Place Statistics. Inclua um código como este:
<c:import url="/js/PlaceStatisticsViewer.js" context="/lotus/PA_Place_Statistics"/>

Deve-se ressaltar que, depois que essa referência é colocada no arquivo JSP, o aplicativo /lotus/PA_Place_Statistics no servidor deve ser iniciado para que o tema funcione corretamente.

Atualize o sideNav.jspf para acessar o widget

Agora é possível examinar a alteração do arquivo sideNav.jspf no tema para incluir o link para lançar a janela do Place Statistics. Esse arquivo está em:
installedApps\QuickrThemeApp.ear\wp.theme.quickrtheme.war\themes\html\Quickr\sideNav.jspf.

Dois campos principais são necessários:

  • Parte da marcação HTML para mostrar o link
  • Uma nova função em Javascript para abrir o widget

A amostra de arquivo sideNav.jspf fornecido com este artigo contém exemplos desse código; essas seções são marcadas com comentários que contêm o texto “PLACESTATS”. Essas partes devem ser copiadas e coladas na sua cópia do arquivo sideNav.jspf, em vez de substituir a cópia do arquivo no seu servidor pelo arquivo contido neste artigo.

Uma nova função para exibir o widget é colocada na parte inferior do script. É necessário passar o placeId, a raiz de contexto do tema e a raiz de recurso do tema na função para que possam ser passados ao widget.

A marcação para mostrar o link na UI deve estar contida em uma condição baseada na definição da variável isApplicationManager como true, para que o link só seja exibido se o usuário atual for um gerente. Também é necessário conter um pouco de código para obter a raiz de contexto do tema e a raiz de recurso do tema. Essa tarefa é realizada usando o código mostrado na listagem 11.

Listagem 11. JSP para mostrar o link do Place Statistics no tema do 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 >

O link para acessar o widget é definido como um elemento <a>. Inclui um manipulador de eventos de onclick que chama a nova função para mostrar o widget, passando o placeID, a raiz de contexto do tema e a raiz de recurso do tema.

Para terminar, é necessário alterar o registro de data no arquivo Default.jsp para que as mudanças no tema entrem em vigor. Esse arquivo está em:
installedApps\QuickrThemeApp.ear\wp.theme.quickrtheme.war\themes\html\Quickr\Default.jsp

Uma forma de alterar o registro de data e hora é abrir o arquivo em um editor de texto e salvá-lo.


A aparência

Depois que você faz as mudanças, o novo link é mostrado abaixo do menu de navegação à esquerda, como mostra a figura 3.

Figura 3. Navegação à esquerda com o Place Statistics incluído
Navegação à esquerda com o Place Statistics incluído

Quando se clica no link do Place Statistics, é exibida uma janela que se parece com a janela mostrada na figura 4.

Figura 4. Place Statistics exibido na interface com o usuário da Web para gerentes de local
Place Statistics exibido na interface com o usuário da Web para gerentes de local

Quando se clica no link Download Statistics na parte inferior da janela, é exibida a janela usual de download do navegador, dando o nome padrão placestatistics.csv ao arquivo. O arquivo pode ser salvo ou aberto usando um programa que aceite arquivos CSV como entrada, como o IBM Lotus Symphony™.


Usando as estatísticas transferidas por download

Agora que você tem um mecanismo para que os proprietários de locais façam o download das estatísticas sobre os locais, eles se interessarão em saber quais estatísticas estão disponíveis e quais relatórios podem ser executados.

Os proprietários de locais podem acessar dados estatísticos em nível de local:

  • Número total de conteúdos
  • Tamanho total dos conteúdos (KB)
  • Número total dos conteúdos incluídos no dia atual
  • Número total de conteúdos atualizados no dia atual
  • Número total de conteúdos da Web (posts de blog, página de wiki, comentário)
  • Número total de documentos
  • Número total de conteúdos da Web incluídos hoje
  • Número total de conteúdos da Web atualizados no dia atual
  • Número total de documentos incluídos no dia atual
  • Número total de documentos atualizados no dia atual
  • Número total de posts de blog
  • Número total de páginas de wiki
  • Número total de comentários

A Figura 5 ilustra uma amostra de estatísticas em nível de local transferidas por download em um arquivo com o formato CSV.

Figura 5. Amostra de estatísticas no formato comma-separated value (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 ......
......

É possível abrir o arquivo CSV transferido por download usando Lotus Symphony Spreadsheets, Microsoft Excel ou o aplicativo de planilha de sua preferência e criar gráficos baseados nos dados estatísticos. As Figuras 6 e 7 são dois gráficos baseados no "Número total de conteúdos" e no "Tamanho total dos conteúdos (KB)" usando o Lotus Symphony Spreadsheets.

Figura 6. Exemplo de gráfico que mostra o número de conteúdos dos locais
Exemplo de gráfico que mostra o número de conteúdos dos locais
Figura 7. Gráfico que mostra o tamanho total dos conteúdos
Gráfico que mostra o tamanho total dos conteúdos

O arquivo CSV que contém os dados estatísticos referentes a esses gráficos está contido no Apêndice 2 deste documento.


Conclusão

Este artigo mostra como usar os serviços do Place Statistics fornecidos no Lotus Quickr 8.5 para apresentar uma UI que mostra os dados e fornece o recurso de exportar os dados estatísticos para outros aplicativos.

A produção de feeds de vários formatos usando o Abdera e a API do WebSphere Portal foi demonstrada, juntamente com o código que mostra como esses feeds podem ser consumidos.

Este artigo também serve como introdução à inclusão de widgets em Dojo no tema do Lotus Quickr 8.5. A técnica de construir uma janela em Dojo e vincular a uma instância disso no tema pode ser usada em várias situações diferentes.


Apêndice 1: amostra de feed 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>

Apêndice 2: arquivo CSV para os gráficos

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

Download

DescriçãoNomeTamanho
Código de amostraplace.zip3.51MB

Recursos

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Lotus
ArticleID=599961
ArticleTitle=Estatísticas de uso do IBM Lotus Quickr: Medindo o Sucesso da Colaboração em Equipe
publish-date=12062010