Avançar para a área de conteúdo

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

Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

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

  • Fechar [x]

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.

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

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

  • Fechar [x]

Criando um componente personalizado no IBM Lotus Quickr visando à integração com o IBM Lotus Sametime Unyte Meeting

Stephen Wills, Software Engineer, IBM
Stephen Wills é engenheiro de software e atua no Laboratório de Software de Dublin da IBM na Irlanda. Ele trabalha com o produto IBM Lotus Quickr, principalmente na área de elaboração de modelos. Entre em contato com Stephen através do e-mail stephen_wills@ie.ibm.com.
Ramajeyam Gopalraj, Advisory Software Engineer, IBM
Ramajeyam Gopalraj é um Conselheiro de Engenharia de Software que trabalha com a equipe Lotus Quickr no Research Triangle Park, NC. Entre em contato com Ramajeyam através do e-mail ramajeyam_gopalraj@us.ibm.com.
Artur Grzenkowicz, Senior Software Engineer, IBM
Artur Grzenkowicz é engenheiro senior de software e trabalha no Laboratório de Software de Dublin da IBM na Irlanda. Ele trabalha com a Plataforma Java, na área de modelos do Enterprise Edition Lotus Quickr. Entre em contato com Artur através do e-mail agrzenko@ie.ibm.com.
Jonathan Brunn, Software Architect, IBM
Jon Brunn é o arquiteto do Lotus Quickr visando à integração com o Enterprise Content Management. No momento, Jon atua na linha do produto Lotus Quickr, principalmente nas áreas de ampliação, personalização e integração corporativa. Entre em contato com Jon através do e-mail jbrunn@us.ibm.com.
(Autor Plus do developerWorks)

Resumo:  Este artigo explica como os serviços do IBM® Lotus® Quickr™ para o WebSphere® Portal podem ser ampliados com o desenvolvimento de componentes personalizados. Os componentes personalizados podem ser desenvolvidos para acrescentar mais recursos e integrarem-se com outros produtos de software e aplicativos.

Data:  30/Jun/2009
Nível:  Intermediário
Atividade:  5617 visualizações
Comentários:  


Nota do editor: Você sabe bastante sobre este tópico? Quer compartilhar seu conhecimento? Participe hoje do programa wiki sobre o software IBM Lotus.

wiki sobre o Lotus Quickrwiki sobre o Lotus Sametime Unyte Meeting

Apresentação

Para ilustrar os conceitos, foi desenvolvido um exemplo real e que pode ser implementado, que permite que seções do Lotus Quickr sejam integradas com o IBM Lotus Sametime® Unyte® para fornecer um recurso de reunião on-line instantânea. Além dos desenvolvedores de Lotus Quickr, esse artigo também pode beneficiar potencialmente aqueles que visam se aprimorar quanto ao Lotus Sametime Unyte API. No entanto, o principal enfoque desse artigo é explicar as etapas de desenvolvimento dos componentes para Lotus Quickr. Se você estiver buscando a adição do recurso de reunião instantânea à sua seção do Lotus Quickr, poderá implementar o exemplo utilizando as instruções fornecidas nesse artigo e usá-lo como ele se apresenta.

Esse artigo destina-se a desenvolvedores de aplicativos que possuem conhecimento sobre Java™, XML e desenvolvimento de portlets. Parte do conhecimento sobre APIs baseadas em REST seria útil para compreender o exemplo de código usado nesse artigo.

O Lotus Quickr é um software colaborativo usado pelas equipes para compartilhar conteúdo.

O Lotus Quickr pode ser descrito por três termos fundamentais: armazenamento de conteúdo, colaboração entre equipes e conectores.

  • O Lotus Quickr é um repositório de conteúdo no qual usuários e equipes armazenam conteúdo pessoal e da equipe.
  • Ele possibilita a colaboração entre equipes, permitindo que os usuários armazenem, organizem, acessem e compartilhem conteúdo e projetos da equipe.
  • Ele fornece ao usuário uma interface para o conteúdo do Lotus Quickr.

Uma das ferramentas projetadas para a colaboração é o Lotus Sametime Unyte Meeting.

O Lotus Sametime Unyte fornece serviços integrados de Web, voz e videoconferência para clientes específicos, de indivíduos, pequenas empresas e departamentos a grandes multinacionais. O Lotus Sametime Unyte oferece interfaces de programação de aplicativos (APIs) para fornecedores que buscam uma integração rápida e fácil do Lotus Sametime Unyte com outros produtos e serviços existentes, e outros produtos IBM, como o IBM WebSphere Portal e o Lotus Quickr. A API baseada em URI permite que as empresas conectem o Lotus Sametime Unyte ao seu aplicativo.

Este artigo descreve como integrar o Lotus Sametime Unyte Meeting com seções do Lotus Quickr 8.1.1. Nas próximas seções desse artigo, um exemplo da Plataforma em Java do Lotus Sametime Unyte Meeting, o componente do Enterprise Edition Lotus Quickr que suporta a integração, é descrito e analisado. Porém, em primeiro lugar, faremos uma introdução básica aos componentes de criação e sua função no Lotus Quickr.


Componentes no Lotus Quickr

Nesta seção, descrevemos as etapas que você deve seguir para criar um componente típico que possa ser implementado ao Lotus Quickr. Conforme o nome sugere, os serviços do Lotus Quickr para WebSphere Portal são criados no WebSphere Portal. Em especial, ele utiliza a infraestrutura composta de aplicativos (CAI) oferecida pelo WebSphere Portal.

A CAI define interfaces que podem ser implementadas para desenvolver novos componentes que ampliam os recursos do Lotus Quickr. Entrar em detalhes sobre toda a estrutura vai além do escopo desse artigo. (Para obter mais detalhes sobre a estrutura, consulte os materiais relacionados na seção Recursos desse artigo). Concentramo-nos nas interfaces necessárias para criar um componente. A documentação referente a essas interfaces localizada aqui também pode ser consultada:

<Quickr Install Location>/PortalServer/doc/Javadoc/spi_docs

Os componentes do Lotus Quickr são usados dentro das seções do Lotus Quickr. O componente pode ser tão simples quanto um portlet. Um componente razoavelmente complexo poderia utilizar sua própria biblioteca para armazenar conteúdo, definir funções personalizadas que são usadas para padronizar sua funcionalidade e participar de operações de backup e restauração.

Criação de um componente

Siga estas etapas para criar um componente:

  1. Desenvolva o portlet que fornece a interface de usuário e outros recursos do componente.
  2. Desenvolva o manipulador de componentes ao implementar as interfaces CAI adequadas.
  3. Forneça um arquivo plugin.xml que especifica o manipulador de componentes (normalmente na raiz do arquivo JAR que contém a implementação do componente, que está contida no arquivo WAR).
  4. Vincule o portlet e o manipulador de componentes usando o arquivo portlet.xml.

Deve-se observar que o manipulador de componentes pode estar contido no arquivo WAR do portlet ou em um arquivo JAR separado, disponibilizado no caminho de classe. Na inicialização do servidor, a CAI tenta criar um registro de todos os componentes implementados. Isso é feito carregando-se todos os arquivos plugin.xml que estão visíveis no caminho de classe. O arquivo plugin.xml referente ao componente deve fornecer o ponto de extensão para o componente de negócios CAI, ou seja, com_ibm_portal_app.BusinessComponents

A listagem 1 oferece um exemplo.


Listagem 1. Exemplo de declaração de plug-in do componente
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="sample.plugin" version="1.0.0">
   <extension
       point="com_ibm_portal_app.BusinessComponents"
       id="MyFirstComponent">
        <provider class="sample.MyFirstHandler">
        </provider>
   </extension>
</plugin>

OBS.: Certifique-se de que o número da versão inclua três partes.

A classe do provedor especificada no arquivo plugin.xml é onde todas as interfaces necessárias para participar como um componente na seção devem ser implementadas. A CAI define um conjunto de interfaces do qual um componente irá participar; eles são os seguintes:

  • Ciclo de vida. Esta interface define os retornos necessários que o componente pode implementar para que possa atentar para eventos como criação e exclusão da instância do componente em uma seção. A CAI tenta solicitar o método apropriado nessa interface quando esses eventos ocorrem.
  • Associação. A interface da associação define os métodos de retorno para atentar aos eventos associados ao controle de acesso, como adição ou remoção de acesso de um ou mais usuários ao componente. O componente pode usar essa interface para desempenhar operações adicionais quando tais eventos ocorrerem.
  • Serializável. Os componentes implementam essa interface para participar as operações de backup e de restauração para as seções. Quando é realizado o backup de uma seção do Lotus Quickr, cada componente recebe uma notificação para fazer backup do seu próprio conteúdo. Se o componente não gerenciar seu próprio conteúdo, não será necessário implementar essa interface.
  • Passível de gerar modelos.Qualquer seção do Lotus Quickr pode ser salvo como um modelo. Esse recurso permite que você crie rapidamente uma nova seção com o mesmo conjunto de componentes. Quando uma seção for salva como um modelo, a CAI notificará cada componente na seção usando essa interface. Ao implementar essa interface, os componentes poderão salvar seu status no modelo de forma que possam recuperá-lo quando uma nova instância for criada a partir do modelo.

Nem todas essas interfaces são obrigatórias. Conforme mencionado anteriormente, você pode criar um portlet simples para oferecer o recurso e usá-lo dentro de uma seção do Lotus Quickr. Fornecer a implementação para uma ou mais dessas interfaces é o que diferencia um portlet de um componente. Você deve avaliar a necessidade de implementar essas interfaces dependendo do requisito.

Finalmente, após criar o portlet, o manipulador de componentes e o arquivo plugin.xml, deve-se atualizar o arquivo portlet.xml para vincular o portlet ao componente. Ao desempenhar essa etapa, você permite que a CAI considere esse portlet como um componente de negócios e passe a solicitar os métodos apropriados no manipulador de componentes. Tudo o que precisa ser feito para fazer essa vinculação é adicionar a preferência mostrada na listagem 2 no arquivo portlet.xml.


Listagem 2. Preferência do portlet vinculando um manipulador de componentes ao portlet
<portlet-preferences>
  <preference>
    <name>com.ibm.portal.bc.ref</name>
    <value>portal:extreg/sample.plugin.MyFirstComponent</value>
  </preference>
</portlet-preferences>

O valor para essa preferência contém duas partes. Primeiro, ele tem o prefixo portal:extreg/. Trata-se do prefixo JNDI para todas as referências dos componentes de negócios. A segunda parte é, na verdade, a combinação do ID de plugin (sample.plugin) e do ID do ponto de extensão (MyFirstComponent) fornecida em nosso arquivo plugin.xml.


Exemplo: componente Sametime Unyte Meeting

Esse exemplo detalha como criar um componente personalizado para utilizar nas seções do Lotus Quickr. O exemplo que é usado para ilustrar esse componente é um portlet de reuniões do Lotus Sametime Unyte, que permite que os membros de uma seção iniciem reuniões do Lotus Sametime Unyte usando sua conta pessoal do Lotus Sametime Unyte e, em seguida, possibilita que outros membros da equipe participem da reunião. O componente usa um portlet como um frontend para um componente de negócios da CAI (Infraestrutura Composta de Aplicativos, o tempo de execução do componente para as seções). Esse componente de negócios acessa o serviço do Lotus Sametime Unyte usando o Lotus Sametime Unyte Meeting Server API.

O exemplo que portlet que é criado permite que os membros de uma seção acessem as reuniões do Lotus Sametime Unyte. Uma reunião pode ser iniciada por membros da seção inserindo-se os detalhes de sua conta pessoal do Lotus Sametime Unyte em um formato simples conforme mostrado na figura 1.


Figura 1. Visão do portlet quando a reunião não está ocorrendo
Portlet view when meeting is not in session

Clicar no botão Host Meeting abre a interface do usuário do Lotus Sametime Unyte Web Conference no modo do apresentador em uma nova janela do navegador. Agora, quando outros membros da seção dirigem-se ao portlet, eles obtêm uma visualização que mostra os detalhes da sessão de reunião atual e um botão que os permite participar da conferência conforme mostrado na figura 2.


Figura 2. Visão do portlet quando a reunião está ocorrendo
Portlet view when meeting is in session

Após o término de uma reunião, uma visualização é exibida, mostrando os detalhes da reunião anterior e do formato usado para iniciar uma nova sessão de reunião. Finalmente, o portlet suporta um modo Edit Settings, apresentando um formato simples que permite que os usuários alterem a configuração do serviço da reunião usado pelo componente.

Interação dos componentes

A Figura 3 mostra como os diversos componentes desse exemplo estão estruturados e interagem.


Figure 3. Interação dos componentes
Component interaction

As próximas seções detalhem a forma como essas partes integrantes são organizadas e interagem, começando pelo servidor do Lotus Sametime Unyte Meeting e passando para o componente de negócios antes de encerrar com uma abordagem sobre o portlet de reuniões que funciona como uma visualização para o componente de negócios.

Implementação do exemplo

No exemplo de código associado a esse artigo, pode-se encontrar uma cópia criada previamente do componente. Na pasta Deployment, localize o arquivo unyte.meetings.war. Esse arquivo deve ser copiado para a pasta installableApps em sua implementação do Lotus Quickr:

<quickr>/PortalServer/installableApps

O exemplo é implementado usando-se um script xmlaccess fornecido. Xmlaccess é uma interface de script que fornece acesso aos comandos de configuração para o WebSphere PortalServer. Para atribuir um nome exclusivo ao portlet (exigido para incluir o componente na paleta de componentes, é necessário implementar o componente usando xmlaccess. (Se o componente não estiver incluído na paleta, então a interface do usuário de implementação do módulo Lotus Quickr Web na seção Administration pode ser usada.) O script xmlaccess também está localizado na pasta Deployment do código disponível na seção Download do artigo. O script é relativamente simples; ele implementa o módulo Web e, em seguida, atribui um nome exclusivo para o portlet. Para obter mais informações sobre xmlaccess, consulte o Centro de Informações. Um conjunto abrangente de exemplos de scripts também pode ser encontrado na pasta <quickr>/PortalServer/doc/xml-samples.

Para executar o script, primeiro é necessário copiá-lo no servidor. Em seguida, acesse a pasta <quickr>/PortalServer/bin. O script xmlaccess (xmlaccess.bat / xmlaccess.sh) pode ser executado, fornecendo parâmetros que especificam o usuário administrador e a senha, e direcionando para o script de implementação:

xmlaccess – url <configurl> –user <adminuser> -password <adminpwd> -in /temp/deployUnyteSample.xml

Onde adminuser é o ID do usuário administrador, adminpwd é a senha correspondente, o parâmetro in aponta para o script de implementação e o parâmetro url indica o URL de configuração do Portal (normalmente http://<host>:10038/lotus/config).

Após implementar o componente, se você quiser continuar testando-o diretamente, poderá passar para a seção sobre como adicionar o componente à paleta abaixo. Essa etapa é opcional; se você não incluir o componente na paleta, ele ainda poderá ser adicionado às seções ao inserir o portlet (Sametime Unyte Meeting) no lugar.

Após implementar o componente, o servidor terá de ser reinicializado porque o componente inclui uma extensão do servidor. Essas extensões são carregadas no registro de extensão na inicialização do servidor.


Lotus Sametime Unyte Meeting Server API

O Lotus Sametime Unyte oferece uma API de gerenciamento de conferências via Web para ser utilizado por parceiros e clientes visando à integração dos recursos desse tipo de conferência aos seus aplicativos. A API baseia-se em HTTP e geralmente funciona em uma conexão protegida que utiliza SSL. As chamadas da API são organizadas transmitindo-se uma solicitação API do formato de dados XML enviados por meio de HTTP(S) a um URL com ponto de entrada único anunciado. Ambos os métodos GET e POST podem ser usados, com o mesmo recurso disponível para cada um deles (com um formato de solicitação um pouco diferente). Esse exemplo utiliza o método GET para expedir solicitações, mas ele poderia ser facilmente alterado para usar o método POST. Para facilitar, o exemplo não usa SSL; no entanto, visando à utilização em sistemas de produção, o SSL provavelmente seria uma exigência.

O Lotus Sametime Unyte Meeting Server API oferece acesso aos serviços listados na tabela 1.


Tabela 1. Serviços oferecidos pelo Lotus Sametime Unyte Meeting Server API
ServiçoFunção
Gerenciamento da sessãoInício das reuniões, no modo off-line e de apresentação; participação nas reuniões; remoção dos participantes das reuniões; obtenção dos detalhes de uma sessão de reunião atual ou histórica; alteração dos atributos de uma reunião em andamento
Gerenciamento de itensGerenciamento (criação, exclusão e atualização) dos itens de serviço, como clientes, assinantes e grupos de portas
Gerenciamento de conteúdoPublicação e exclusão de apresentações no servidor; início de uma apresentação em uma reunião em andamento; interrupção de uma apresentação atual; recuperação de apresentações a partir do servidor; recuperação dos registros da sessão
Retornos do gerenciamento da sessãoUm conjunto de retornos que podem ser usados para ativar o processamento de aplicativos específicos em eventos de serviço, como início e término da sessão de conferência, e inclusão do participante e eventos de saída
Além dessas seções da API, esse exemplo utiliza apenas chamadas da área de gerenciamento das sessões. De maneira específica, as APIs que geram URLs que podem ser usadas para iniciar e participar de sessões de reuniões são usadas, além da API para obter os detalhes de uma determinada sessão.

Formato das chamadas da API

As chamadas à API assumem a forma de uma solicitação HTTP para um URL de ponto de entrada de serviço conectado, incluindo detalhes da solicitação como dados XML. Por exemplo, usamos o formato GET da solicitação; o padrão URL para tal é:

http://<service_entry_point>/register/api/main.asp?xml=<xmlstring>

em que <xmlstring> consiste nos detalhes da solicitação como XML. O formato referente ao XML depende da API especificada a ser usada. Para usar a API para iniciar a sessão de uma reunião, o XML mostrado na listagem 3 é exigido.


Listagem 3. Formato do XML da solicitação Início da Reunião
<WDAPI ver="1.1" type="call" name="startSession" utc="utc_milliseconds">
	<PARAMETERS>
		<SUBSCRIBER subscriber_parameters_list />
		<VAPI vapi_parameters_list />
		<SESSION session_parameters_list />
		<PARTICIPANT participant_parameters_list />
		<BRAND brand_parameters_list>
			brand_override_elements_list
		</BRAND>
	</PARAMETERS>
	<CHECK check_parameter_list />
</WDAPI>

em que nome especifica o método da API que está sendo solicitado e utc_milliseconds é o horário UTC em milissegundos (em Java, que é equivalente à chamada System.currentTimeMillis()). Há duas seções principais no restante do XML. O segmento PARAMETERS contém todos os detalhes da solicitação. Nem todos esses detalhes são usados nesse exemplo, como a seção VAPI, que contém detalhes de conferência por voz, e a seção SESSION, que permite que algumas opções adicionais sejam fornecidas para a sessão da conferência. Nesse exemplo, as partes importantes são a seção SUBSCRIBER, que contém detalhes sobre o serviço e determina a identidade de quem iniciou a reunião, e a seção PARTICIPANT, que define como os detalhes da pessoa que está iniciando sejam exibidos na interface do usuário do Lotus Sametime Unyte Meetings Web para os outros participantes.

Wrapper em Java ao redor do Meeting Server API baseado em HTTP

Como o componente baseia-se em Java, crie um wrapper em Java ao redor do Meeting Server API baseado em HTTP para ser usado pelo seu componente. Esse wrapper oculta detalhes de implementação, como a criação do XML de solicitação da API e a geração de hashes de segurança que são usados no mecanismo de autenticação (consulte a seção abaixo) a partir do restante do componente. Como parte desse wrapper, crie também classes para representar cada uma das seções de dados da solicitação da API (assinante, marca e assim por diante) visando à conveniência quanto do código cliente que precisa expedir as solicitações do Meeting Server API.

Essas classes de wrapper estão localizadas no pacote com.ibm.quickr.meetings.unyte.service. Primeiro, observe a classe SametimeUnyteService, que contém o método getStartSessionURL(...). Esse método reúne o XML de solicitação referente à chamada do Meeting Server API para iniciar uma nova sessão de conferência na Web no Lotus Sametime Unyte. Além disso, esse método resulta em uma nova janela do navegador sendo aberta com a interface do usuário de conferências do Lotus Sametime Unyte no modo do apresentador. Observe como um conjunto de objetos de wrapper é usado para transmitir parâmetros no método getStartSessionUrl(…). A partir desses parâmetros, a solicitação XML é criada. Para obter mais detalhes, consulte os comentários no código de origem incluído.

A geração de XML para as seções de parâmetros individuais é delegada a outro conjunto de classes que desempenha a tarefa de criar o XML para um determinado método de API, validando se todos os parâmetros exigidos para aquele método estão presentes e gerando o hash MD5 usado como parte do modelo de segurança da API (consulte a seção abaixo). Por exemplo, a classe Subscriber integra os dados do assinante que compõem parte de uma solicitação (uma solicitação de sessão de início, por exemplo). Ela inclui métodos getter e setter para todos os parâmetros participantes, além da lógica de validação para assegurar que todos os parâmetros exigidos para aquela determinada chamada do método estejam presentes. O método getRequestXml(...) gera os dados XML para a sessão a ser incluída no elemento PARAMETERS na solicitação e o método generateCheck() gera o valor do hash a ser incluído no elemento CHECK.

A classe SametimeUnyteService fornece métodos para lidar com URLs de solicitação de geração para iniciar e participar de uma sessão de reunião e um método para determinar o status de uma sessão específica. Para obter mais informações a esse respeito e sobre o conjunto completo de objetos fornecidos como parte do wrapper em Java ao redor do Meeting Server API que foi criado para esse componente, consulte o exemplo de código incluído na seção Download desse artigo, que conta com vários comentários.

Solicitações de Validação do Meeting Server API

O Meeting Server API usa um procedimento de hashes de segurança para validar as solicitações atribuir um limite de tempo de 10 minutos ao ciclo de vida de cada solicitação depois que o ponto foi gerado (um registro de data e hora é incluído como parte desse procedimento de hash). Observe o formato geral do XML referente a uma solicitação de sessão de início (consulte as seções destacadas) mostradas na listagem 4.


Listagem 4. Formato geral do XML da solicitação Sessão de Início
<WDAPI ver="1.1" type="call" name="startSession" utc="utc_milliseconds">
  <PARAMETERS>
    <SUBSCRIBER subscriber_parameters_list />
    <VAPI vapi_parameters_list />
    <SESSION session_parameters_list />
    <PARTICIPANT participant_parameters_list />
    <BRAND brand_parameters_list>brand_override_elements_list</BRAND>
  </PARAMETERS>
  <CHECK check_parameter_list />
</WDAPI>

O atributo utc é um registro de data e hora que representa o horário da geração da solicitação da API. A seção de verificação contém as versões em hash das seções do parâmetro de solicitação do XML, neste formato mostrado na listagem 5.


Listagem 5. Verifique a seção do XML de solicitação
<CHECK subscriber="2b0694d2660ab919b6a2d19a061884d3"
	 vapi="2b9694d22667a9acc6a2d19a068884d4"
	 session="2b0694d2660ab919b6a2d19a06188a99"
	 participant="2b9694d2260ab9acc6a2d19a061884d6"
	 brand="2b0694d2660ab919b6a2d19a06188b97"/>

Cada atributo de verificação constitui um hash MD5 (um algoritmo do trecho da mensagem usado comumente na geração de hashes criptográficos) da seguinte cadeia de caractere concatenada:

<private_token> + <utc_time> + <element_string>

em que private_token é um token secreto conhecido somente pelo provedor do serviço e pelos clientes API confiáveis, utc_time é o horário da geração da solicitação (o mesmo que o atributo utc no elemento WDAPI) e a cadeia de caractere do elemento é o conteúdo completo do elemento correspondente. O resultado do hash de 128 bits é representado em uma cadeia de caractere com 32 dígitos hexadecimais.

Esse procedimento de hash é implementado como parte do wrapper em Java ao redor do Meeting Server API que está incluído como parte desse exemplo. Para obter mais detalhes sobre a implementação, consulte as seções na classe SametimeUnyteService que reúne o XML de solicitação e o método generateCheck(...), que é implementado em cada uma das classes que lidam com parâmetros específicos (Subscriber, Session e assim por diante).


Implementação do componente de negócios

A interface do ciclo de vida

A classe de implementação do componente de negócios é MeetingsBCHandler, localizada no pacote com.ibm.quickr.meetings.unyte.bc. Essa classe corresponde ao contrato do componente de negócios com a arquitetura CAI ao implementar interfaces do Componente SPI da CAI. Dessas interfaces, a mais importante para esse exemplo específico é a interface do ciclo de vida. São necessárias instâncias desse componente para manter um status (acompanhar itens como o ID da sessão de reunião atual ou a descrição da reunião anterior) e a infraestrutura de CAI no WebSphere Portal V6.0.1 (na qual o Lotus Quickr 8.11 baseia-se) não fornece suporte para manter propriedades no nível da instância do componente. Sendo assim, as implementações de componentes individuais têm de implementar seu próprio mecanismo de armazenamento para quaisquer dados associados à instância dos componentes. Normalmente, essa implementação seria armazenada em um banco de dados ou em um documento JCR, mas tendo em vista a simplificação desse exemplo, o componente usa um arquivo no sistema de arquivos como a base para armazenar um conjunto de pares entre nome e valor que são utilizados para manter o status do componente. Cada instância do componente tem um arquivo separado associado a ele para armazenar seu status, que deve ser criado como parte da inicialização da instância do componente e eliminado (ou seja, excluído) com a destruição do componente. Para desempenhar essa tarefa, implemente métodos na interface do ciclo de vida.

O método createInstance(...) é chamado em um componente de negócios no ponto em que uma nova instância daquele componente é criado. Em geral, essa chamada ocorre quando um portlet que é associado como a visualização daquele componente de negócios (consulte a seção abaixo sobre a relação entre portlets e componentes de negócios) é acrescentado a uma seção. A Listagem 6 mostra o método createInstance(...) a partir desse exemplo.


Listagem 6. O método createInstance(…) do manipulador de componentes
public ListModel createInstance(ListModel parameters) throws ComponentException {
  try {
    String timestamp = Long.toString(System.currentTimeMillis());
    String bcId = "unyte_meeting_" + timestamp;
        
    ConfigFileHelper configHelper = ConfigFileHelper.createConfigFile(bcId);
    configHelper.setConfigParam("teamspace.meetings.bc.svcUrl", 
    "http:/conferenceserver.renovations.com/register/api/main.asp");
    configHelper.setConfigParam("teamspace.meetings.bc.svcProv", "SVC_PROV");
    configHelper.setConfigParam("teamspace.meetings.bc.billingType", "t");
    configHelper.setConfigParam("teamspace.meetings.bc.validationCode", "XXXX");
    configHelper.setConfigParam("teamspace.meetings.bc.brandName", "RENOVATIONS");
    configHelper.setConfigParam("teamspace.meetings.bc.meetingDesc", "---");
        
    ArrayList list = new ArrayList();
    list.add(new VariableImpl("id", "id", "the id", bcId));
        
    return ListModelHelper.from(list);
  }
  catch(MeetingServiceException mse) {
    throw new ComponentException(mse);
      }
}

Nesse caso, o método createInstance(...) desempenha duas ações importantes. Primeiro, ele cria o arquivo de armazenamento de configuração que é usado para armazenar o status dessa instância. Uma classe do ajudante, ConfigFileHelper (localizado no mesmo pacote com.ibm.quickr.meetings.unyte.bc) é fornecido para essa finalidade. Ele suporta a criação e a exclusão de arquivos de configuração no sistema de arquivos, além da consulta e da configuração das propriedades individuais dentro desses arquivos (visando ao armazenamento das informações de status). Não abordaremos esta implementação aqui; é insignificante. Para obter mais detalhes, consulte a classe no exemplo de código incluído nesse artigo.

Aqui, ao criar a instância do componente, você desejará preencher alguns detalhes sobre a configuração inicial. Para fins desse exemplo, incluímos uma cópia da configuração do servidor em cada instância do componente e a tornamos acessível por meio do modo editar configurações do portlet (consulte abaixo para obter mais detalhes sobre esse modo personalizado). No método createInstance(...), você desejará preencher alguns padrões para tal.

Em segundo lugar, é responsabilidade do método createInstance(...) atribuir um identificador individual para cada instância do componente no momento da criação; esse ID deve ser exclusivo para todas as instâncias daquele tipo de componente. Esse ID é um elemento exigido da lista em ListModel que deve ser exibido a partir desse método e que é usado para identificar a instância do componente nas interações de CAI subsequentes.

O método removeInstance(...) é chamado após a exclusão da instância do componente, que ocorre quando um portlet que está vinculado ao componente é removido de uma seção ou quando a seção que o contém é excluída. Esse método permite que uma instância do componente realize ações de limpeza personalizada. Esse método é chamado de forma assíncrona; há um daemon de limpeza de componentes executado no servidor uma vez por dia e chama esse método em quaisquer instâncias do componente que foram excluídas desde a última execução. Esse processo também é desempenhado na inicialização do servidor. No caso do seu exemplo de componente, você deseja que o arquivo de configuração relacionado ao componente excluído seja excluído do sistema de arquivos conforme mostrado na listagem 7.


Listagem 7. O método removeInstance(…) do manipulador de componentes
public void removeInstance(String bcId) throws ComponentException {
    try {
        ConfigFileHelper.deleteConfigFile(bcId);
    }
    catch(MeetingServiceException mse) {
        throw new ComponentException(mse);
    }
}

A interface passível de gerar modelos

A interface passível de gerar modelos abrange a serialização do status do componente dentro e fora dos modelos. Um modelo é um documento XML que contém um esboço para a criação de um aplicativo (seção), incluindo os detalhes de todos os seus componentes integrados e as relações entre eles.

O método serializeToTemplate(...) permite que o componente em uma seção registre seu status visando à inclusão no XML do modelo quando a seção for salva como um modelo. Esse exemplo não inclui nenhum manuseio de serialização personalizado (embora ele possa ser alterado, por exemplo, para serializar a parte de configuração do serviço de reuniões do status do componente).

Quando uma nova instância do componente for criada como o resultado de uma nova seção que está sendo elaborada a partir de um modelo que contém o componente, o método createFromTemplate(...) será chamado. Esse método é transmitido nos dados que foram serializados para o modelo durante o método serializeToTemplate(...). Embora nenhum dado tenha sido serializado, o exemplo deve implementar esse método para abranger a inicialização do componente quando a instância for criada como parte de um modelo. Trata-se da mesma inicialização que foi desempenhada no método Lifecycle.createInstance(...); um novo documento de configuração deve ser criado para manter o status da instância do componente. Assim como ocorre com o método Lifecycle.createInstance(...), o método Templatable.createFromTemplate(...) deve gerar e exibir um identificador exclusivo para a nova instância do componente.

Outras interfaces do componente SPI da CAI

Esse componente não implementa nenhuma das outras interfaces do componente (as interfaces do ciclo de vida e passível de gerar modelos são exigidas conforme detalhado acima). O uso de outras interfaces do componente da CAI é opcional. Um componente que teve de expor as funções do componente e gerenciar o acesso de recursos de acordo com essas funções precisaria, por exemplo, implementar a interface de associação, mas a interface poderá ser omitida caso não seja exigida pelo componente. Para obter mais informações sobre as interfaces do componente da CAI, consulte o Javadoc da interface localizado em <quickr>/PortalServer/doc/Javadoc/spi_docs.

Métodos específicos do componente do componente de negócios

Além de implementar interfaces do componente SPI da CAI exigidas, os componentes de negócios normalmente expõem um conjunto de métodos para oferecer suporte para a lógica de negócios do componente. No caso desse exemplo, esses métodos relacionam-se ao gerenciamento de reuniões do Lotus Sametime Unyte: início, participação e obtenção do status de sessões de conferência na Web. Esses métodos são usados pelo portlet que fornece o frontend ao componente de negócios. A classe MeetingsBCHandler inclui esses métodos; eles são agrupados após a implementação da interface do Componente SPI da CAI. Para obter mais detalhes sobre quais desses métodos serão úteis, consulte os comentários que acompanham o código de origem.

Registro do componente na estrutura

Os componentes de negócios da CAI usam uma arquitetura de plug-in, implementada usando o sistema de registro de extensão do WebSphere Application Server para gerenciar extensões do servidor. Para implementar um componente de negócios, as classes de implementação precisam ser disponibilizadas no caminho de classe do sistema com um descritor de plug-in. Como agora a única forma de introduzir um componente de negócios em um aplicativo é ao incluir um portlet que esteja vinculado ao componente de negócios (conforme sua visualização; consulte a seção abaixo), integre os binários do componente de negócios e o descritor de plug-in com o portlet em um arquivo WAR e implemente-o no servidor. Em seguida, a extensão pode ser apanhada pelo registro e a implementação do componente de negócios estará disponível no mesmo escopo.

Para realizar esse registro em nosso exemplo, o descritor de plug-in está integrado no JAR que contém as classes do componente de negócios (e o portlet). Consulte o arquivo plugin.xml no exemplo de código incluído e o código mostrado na listagem 8.


Listagem 8. Declaração de plug-in para o exemplo do componente
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="com.ibm.quickr.meetings.unyte" version="8.1.1">
  <extension point="com_ibm_portal_app.BusinessComponents" id="UnyteMeetingsBC">
    <provider class="com.ibm.quickr.meetings.unyte.bc.MeetingsBCHandler">
    </provider>
  </extension>
</plugin>

Observe principalmente o código em negrito. O ponto de extensão que todos os componentes de negócios da CAI precisam para se associar é com_ibm_portal_app.BusinessComponents. Toda extensão também precisa de um ID, formado por duas partes, o ID de plug-in e o ID de extensão. Finalmente, a classe de implementação do componente de negócios é especificada como o provedor de extensão.

Associação do componente de negócios a um portlet

Os componentes de negócios são introduzidos nas seções vinculando-se um portlet a elas. Em seguida, esse portlet funcionará como uma visualização do componente de negócios. Para criar essa associação, uma preferência de portlet é usada para fornecer uma referência ao componente de negócios que deve ser associado ao portlet. O nome dessa preferência é com.ibm.portal.bc.ref e está especificado no arquivo portlet.xml, conforme mostrado na listagem 9.


Listagem 9. Descritor de plug-in para o exemplo do componente
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app id="UnyteMeetingsPortletApp1"
    xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
    version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd 
    http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
    <portlet>
        <portlet-name>SametimeUnyteMeetingsPortlet</portlet-name>
        <display-name>Sametime Unyte meetings portlet</display-name>
        <portlet-class>
            com.ibm.quickr.meetings.unyte.portlet.SametimeUnyteMeetingsPortlet
            </portlet-class>
        <expiration-cache>0</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>view</portlet-mode>
            <portlet-mode>edit_defaults</portlet-mode>
        </supports>
        <supported-locale>en</supported-locale>
        <portlet-info>
            <title>Sametime Unyte meeting</title>
        </portlet-info>
        <portlet-preferences>
            <preference>
                <name>com.ibm.portal.bc.ref</name>
                <value>portal:extreg/com.ibm.quickr.meetings.unyte.UnyteMeetingsBC
                </value>
            </preference>
        </portlet-preferences>
    </portlet>
    <custom-portlet-mode>
        <portlet-mode>edit_defaults</portlet-mode>
    </custom-portlet-mode>
</portlet-app>

Quando uma instância do portlet for introduzida em uma seção, essa preferência será detectada pelo tempo de execução da CAI e saberá instanciar uma nova instância do componente de negócios e associá-la ao portlet. O formato do identificador do componente consiste em portal:extreg/ prefix (que especifica que o componente pode ser carregado a partir do registro de extensão) e o ID do componente, que consiste no ID de plug-in (com.ibm.quickr.meetings.unyte nesse caso) e o ID de extensão (UnyteMeetingsBC) separado por um ponto.


O exemplo do portlet de reuniões

Estrutura do portlet

O portlet incluído nesse exemplo é um portlet JSR 168 simples. Ele suporta dois modos, um modo de visualização principal para renderizar a interface do usuário para exibir o status da reunião e permitir que os usuários iniciem e participem de reuniões, e um modo editar configurações para permitir que os usuários alterem algumas partes da configuração do componente (os detalhes do provedor de serviço). A classe SametimeUnyteMeetingsPortlet no pacote com.ibm.quickr.meetings.unyte.portlet é a classe de implementação do portlet.

Se você abrir o espaço de trabalho incluído, o layout dos recursos do portlet poderão ser visualizados conforme mostrado na figura 4 (circundados nas duas caixas na figura):


Figura 4. Layout do componente com destaque para os recursos do portlet
Component layout highlighting portlet resources

Renderização da visualização do portlet principal

O JSP de visualização (mainView.jsp) é transmitido no status da sessão por um bean de sessão e, em seguida, gera uma interface de usuário respectiva. Um aspecto a ser observado é o comportamento quando uma reunião acabou de começar ou recebeu a participação de um membro. Nesses casos, o JavaScript é incluído e abre o URL do Meeting Server API (seja para uma chamada startSession ou startParticpiant), além de, em seguida, configurar um cronômetro depois do qual a reunião deve ter encerrado a inicialização e um recarregamento de página é acionado. O restante do JSP é basicamente padrão; para simplificar o exemplo, os estilos e o JavaScript foram incluídos de modo sequencial, enquanto a abordagem mais típica seria externalizar esses itens. Para obter mais informações, consulte a origem JSP no exemplo de código incluído.

Suporte ao modo personalizado editar configurações

O Lotus Quickr usa um modo personalizado de portlet para suportar a ação editar configurações que está disponível na aparência do portlet do Lotus Quickr. O exemplo de portlet utiliza esse modo para apresentar um formato, possibilitando que o usuário edite a configuração do serviço de reuniões para a instância do componente (os detalhes do host de serviço, por exemplo) e salve novamente no componente. Para suportar esse modo personalizado, que é usado pelo Lotus Quickr, primeiro o modo deve ser declarado como um modo personalizado suportado pelo portlet; essa etapa é realizada incluindo-se uma referência a ela no arquivo portlet.xml conforme mostrado na listagem 10.


Listagem 10. Acréscimo de suporte ao modo edit_defaults no descritor de portlet
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app id="UnyteMeetingsPortletApp1"
    xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
    version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd 
    http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
    <portlet>
        <portlet-name>SametimeUnyteMeetingsPortlet</portlet-name>
        <display-name>Sametime Unyte meetings portlet</display-name>
        <portlet-class>
            com.ibm.quickr.meetings.unyte.portlet.SametimeUnyteMeetingsPortlet
            </portlet-class>
        <expiration-cache>0</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>view</portlet-mode>
            <portlet-mode>edit_defaults</portlet-mode>
        </supports>
        <supported-locale>en</supported-locale>
        <portlet-info>
            <title>Sametime Unyte meeting</title>
        </portlet-info>
        <portlet-preferences>
            <preference>
                <name>com.ibm.portal.bc.ref</name>
                <value>portal:extreg/com.ibm.quickr.meetings.unyte.UnyteMeetingsBC
                </value>
            </preference>
        </portlet-preferences>
    </portlet>
    <custom-portlet-mode>
        <portlet-mode>edit_defaults</portlet-mode>
    </custom-portlet-mode>
</portlet-app>

Em seguida, a classe de implementação do portlet deve definir essa personalização como um modo de portlet e verificá-la como parte do método doDispatch(...) (que deve ser sobrescrito) conforme mostrado na listagem 11.


Listagem 11. Definição do modo do portlet
public static final PortletMode EDIT_DEFAULTS_MODE = 
 	new PortletMode("edit_defaults");

protected void doDispatch(RenderRequest request, RenderResponse response) 
	throws PortletException, java.io.IOException {
    WindowState state = request.getWindowState();
    if (!state.equals(WindowState.MINIMIZED)) {
        PortletMode mode = request.getPortletMode();
        if (mode.equals(PortletMode.VIEW)) {
            doView(request,response);
        } 
        else if (mode.equals(PortletMode.HELP)) {
            doHelp(request, response);
        } 
        else if (mode.equals(EDIT_DEFAULTS_MODE)) {
            doEditDefaults(request,response);
        } 
    }
}

Finalmente, o método doEditDefaults(...) expede a solicitação para um JSP (editConfig.jsp), que apresenta um formato que permite ao usuário inserir novos valores referentes à configuração de serviço da reunião.

Inicialização do bean de sessão

O portlet usa um bean de sessão para manter e transmitir pelo portlets e pelo status do componente. Esse bean é inicializado uma vez (no primeiro acesso do portlet em uma sessão) com algumas informações básicas que permanecem constantes referentes à sessão do portlet. Essa inicialização ocorre no método initializeSessionBean(...). As informações sobre o usuário atual e o componente de negócios são registradas. O portlet precisa ser informado sobre dois aspectos do componente de negócios. Primeiro, ele precisa obter uma identificação do componente de forma que possa acessar seus métodos de negócios ao ler a preferência do portlet que identifica o componente de negócios associado (consulte a seção acima). Consulte a listagem 12.


Listagem 12. Obtenção do manipulador de componentes usando a preferência do portlet
private MeetingsBCHandler getBC(PortletRequest request) { 
   try {
    Context ctx = new InitialContext();
    Object bc = ctx.lookup(request.getPreferences().getValue
    ("com.ibm.portal.bc.ref", ""));
    return (MeetingsBCHandler)bc;
  } 
    catch (NamingException e) {
    e.printStackTrace();
    return null;
  }
}

Como as procuras de JNDI são operações dispendiosas, a referência ao BC é procurada uma vez e, em seguida, armazenada para o restante da sessão. Para simplificar, procuramos nosso manipulador de componentes e o vinculamos ao tipo de classe de implementação que conhecemos. Uma abordagem mais típica é dispor de uma interface separada especificando os métodos de negócios do componente por meio do qual o código cliente acessaria o componente.

Para os componentes de negócios da CAI, um objeto da classe do manipulador não é criado para cada instância do componente; em vez disso, todo método no manipulador do componente exige o ID da instância do componente como um parâmetro obrigatório. Por esse motivo, para que o portlet acesse o componente, é necessário determinar o ID da instância do componente de negócios associado a essa determinada instância do portlet. Essa determinação é realizada ao ler outra preferência do portlet, que é gravada pela infraestrutura como parte da inicialização do componente. Essa preferência é com.ibm.portal.bc.instance.id. Ela é configurada de acordo com o valor do ID que foi gerado pelo componente durante o método createInstance(...) ou (createFromTemplate(...) (dependendo do fato da instância do componente ter sido criada como o resultado de um portlet sendo adicionado à seção ou como o resultado de um modelo sendo instanciado):

String bcId = request.getPreferences().getValue("com.ibm.portal.bc.instance.id", "");
sessionBean.setAttribute("bcId", bcId);

Ações no portlet

Há a possibilidade de ocorrerem três ações no portlet, que são tratadas como usuais no método processAction(...) da classe de implementação do portlet. A primeira ação é o início da sessão da reunião, que ocorre quando os usuários preenchem o formulário de detalhes do assinante e clicam no botão Start Meeting. Nesse caso, os valores do formulário são lidos e registrados no bean de sessão e no status do componente, um registro de data e hora é gravado, no qual o tempo limite de inicialização da sessão baseia-se, e o status é modificado para refletir se uma reunião foi iniciada (consulte a seção sobre as variáveis de status abaixo). A segunda ação ocorre quando os usuários participam de uma reunião. Nesse caso, um registro de data e hora precisa ser gravado, no qual o tempo limite da inicialização da interface do usuário da reunião baseia-se. Finalmente, há uma ação que confirma se as opções de configuração do serviço foram alteradas enquanto o portlet estava no modo editar configurações (consulte a seção abaixo). Nesse caso, a nova configuração do serviço da reunião é registrada no componente e o modo de visualização é configurado novamente para a visualização. Para obter mais detalhes, consulte a implementação do método processAction(...).

Determinação do status da sessão da reunião

O portlet utiliza um número de variáveis de status para controlar o fluxo de execução e determinar qual interface do usuário é gerada. Essas variáveis de status são armazenadas centralmente pelo componente de negócios (porque o status precisa ser compartilhado nas múltiplas sessões do portlet que pertencem a diferentes usuários) e lidas a partir daí no bean de sessão que, em seguida, é transmitido pelo portlet (por exemplo, a interface do usuário usa esse bean de sessão para determinar o que é gerado). A tabela 2 exibe uma lista dessas variáveis de status.


Tabela 2. Variáveis de status
Variável de statusFunção
viewState Essa variável registra o status da sessão da reunião e é usada para determinar o que será gerado para a visualização do portlet. Há uma série de status possíveis, incluindo: ativo (uma sessão de reunião está ativa); inativo (uma sessão de reunião não está ativa no momento, mas uma reunião anterior foi realizada); inicial (uma sessão de reunião não está ativa no momento e não ocorreu nenhuma reunião anterior com esse componente); aguardando para iniciar (uma sessão de reunião foi iniciada, mas a conferência da Web ainda não encerrou a inicialização, portanto o ID da sessão não é conhecido e nenhum detalhe da sessão pode ser recuperado); e o status aguardando para participar (os usuários atuais estão aguardando que a interface do usuário de conferência da Web seja inicializada de forma que possam participar da reunião).
lastSessionIdO ID da sessão da última reunião associado a esse componente. Quando uma sessão não está ativa, esse ID é usado para exibir detalhes sobre a última reunião que ocorreu.
lastSessionSubscriberIdO ID de assinante da última reunião associado a esse componente (em conjunto com o ID da última sessão, isso é exigido para recuperar os detalhes da sessão da última reunião caso tenham de ser exibidos).
lastMeetingDescA descrição da sessão da última reunião.
currentSessionIdO ID de sessão da sessão atual quando uma sessão está ativa.
currentSessionSubscriberIdO ID de assinante que foi usado para iniciar a sessão atual quando uma sessão está ativa.
meetingDescA descrição da reunião atual quando uma sessão está ativa.
lastStartActionTimeUm registro do horário no qual a última reunião foi iniciada. Esse registro é necessário porque o portlet tem de permitir uma determinada quantidade de período de concessão enquanto aguarda pela inicialização de uma sessão de reunião. Após esse tempo limite, se a sessão ainda não ocorrer, a inicialização será considerada falha ou abortada; em seguida, o componente retornará para um status inativo.
lastJoinActionTimeUm registro do horário no qual o usuário atual desempenhou a ação para participar da sessão de reunião ativa no momento. Esse registro é usado para gerenciar a interface do usuário enquanto o usuário aguarda pela sessão da conferência para iniciar no modo de participante. Há um tempo limite após o qual a inicialização da sessão da conferência é considerada falha ou abortada, e a interface do usuário reverte para a visualização ativa da sessão da qual o usuário atual não está participando (ou seja, a visualização do botão Join).

Como parte da renderização da visualização, o método getSessionInfo(...) é chamado na classe de implementação do portlet; aqui é onde o status é atualizado (e registrado novamente no componente e no bean de sessão). Consulte o método getSessionInfo(...) para obter detalhes sobre como a lógica de determinação de status é implementada. Em seguida, a solicitação é expedida para o JSP de visualização (mainView.jsp) para gerar a interface do usuário baseada no status da sessão atual.

Adição do componente à paleta de componentes do Lotus Quickr

A última etapa na criação do seu novo componente do Lotus Quickr é disponibilizá-lo na paleta de componentes que é exibida durante a personalização das seções conforme mostrado na figura 5.


Figura 5. Exemplo de componente exibido na paleta de componentes do Lotus Quickr
Sample component displayed in the Lotus Quickr component palette

Siga estas etapas:

  1. Defina as cadeias de caractere para a entrada do componente. Essas cadeias de caractere estão localizadas e são encontradas em um conjunto de arquivos de propriedades. Abra o arquivo

    <quickr>\PortalServer\shared\app\nls\quickr_en.properties e duas cadeias de caractere extras, uma para o título do componente e outra para a descrição:

    unyte.meeting=Unyte Meeting
    new.unyte.meeting=New Unyte Meeting
  2. Salve e feche o arquivo. Essa etapa fornece cadeias de caractere apenas para o idioma inglês. Se for necessário suportar outros idiomas, as variantes dos idiomas correspondentes do arquivo de propriedades também deverão ser editadas.
  3. Adicione a imagem à entrada do componente. Essa imagem, unyteMeeting.gif, está incluída nas origens desse exemplo. Insira essa imagem no diretório a seguir:

    <quickr>\wp_profile\installedApps\<node>\wps.ear\wps.war\themes\html\QPG\images\quickr
  4. Configure alguns estilos. Abra este arquivo:

    <quickr>\wp_profile\installedApps\<node>\wps.ear\wps.war\themes\html\QPG\styles_theme.jspf

    Vá para a seção chamada "customize drop down" (personalizar menu suspenso) e copie as duas definições de estilo usadas pelo componente do calendário na paleta. Em seguida, altere os IDs e o arquivo de imagem mencionado, conforme mostrado na listagem 13.


Listagem 13. Adição de estilos à entrada da paleta de componentes
div.actionSelect li.unyteMeeting{
	background: ${colors.actionSelectBackground} 
	url("images/quickr/unyteMeeting.gif") 
	${requestScope.cssRules.bidiLeft} 50% no-repeat;
}

#teamSpaceAddComponentForm h2.unyteMeeting{
	background: ${colors.actionSelectBackground} 
	url("images/quickr/unyteMeeting.gif") 
	${requestScope.cssRules.bidiLeft} 50% no-repeat;
}

  1. Salve e feche o arquivo.
  2. Em seguida, será necessário adicionar a entrada do componente à paleta. Abra o seguinte arquivo:

    <quickr>\wp_profile\installedApps\<node>\wps.ear\wps.war\themes\html\QPG\pageHeaderContent.jsp

    Pesquise um div com o ID customizePage2. Abaixo desse div está localizado o conjunto de entradas do componente referente à segunda página na paleta. Utilize uma das entradas existentes como uma base a partir do qual irá trabalhar.

  3. Copie o <li> elemento, que representa a entrada do componente do calendário e cole uma nova cópia daquela seção imediatamente após o calendário. Agora altere a classe para corresponder ao estilo que foi criado na última etapa.
  4. Altere as cadeias de caractere para corresponder àquelas que você criou para seu componente. Elas são procuradas a partir de um pacote de recursos, portanto são as chaves no pacote cuja especificação é necessária.
  5. A janela que adiciona o componente utiliza o ID exclusivo do portlet para acrescentá-lo à seção. É necessário transmitir essa ação para a chamada de função showTeamSpaceAddComponentForm(…). Agora você tem o código mostrado na listagem 14.

Listagem 14. Adição da nova entrada à paleta de componentes
<li class="unyteMeeting">
<a href="#" 
   onClick="javascript:showTeamSpaceAddComponentForm("
   <%=MarkupUtil.htmlAttributeEscape(MarkupUtil.jsEscape(pageHeaderText.getString
   ("unyte.meeting")))%>", "<%=MarkupUtil.htmlAttributeEscape
   (MarkupUtil.jsEscape(pageHeaderText.getString("new.unyte.meeting")))%>
   ", "<%= applicationID %>", "wps.p.unyteMeeting", 
   true, nodesOnLevel, true, 'unyteMeeting')"
   class="picture">
	<portal-fmt:text key="unyte.meeting" bundle="nls.quickr"/>
</a>
</li>

Depois que essas alterações forem concluídas, será necessário interferir nos arquivos JSP temáticos que incluem fragmentos .jspf que foram editados para forçar uma operação de recompilação que contém as alterações. Essa tarefa é desempenhada ao salvar o JSP (sem editar; é necessário alterar o registro de data e hora da modificação). Os arquivos que precisam ser salvos dessa forma são styles.jsp e Default.jsp.


Conclusão

Nesse artigo, demonstramos uma forma simples de integrar os serviços do Sametime Unyte às seções do Lotus Quickr. A seção do Lotus Quickr com o recurso do Lotus Sametime Unyte permite que os usuários iniciem conferências na Web ou programem uma delas a partir dos aplicativos que utilizam diariamente.

O principal objetivo de usar o software de conferências na Web é permitir que as pessoas conversem e compartilhem informações com qualquer um, a qualquer momento e em qualquer lugar. Isso ajuda as empresas a tomar decisões mais rápido e economizar capital ao reduzir as viagens.

Em resumo, o Lotus Sametime Unyte Web conferencing integrado no Lotus Quickr pode ajudar os clientes IBM a fazer o seguinte:

  • Solucionar problemas e fazer perguntas e obter respostas por meio de canais de comunicação de alta qualidade
  • Criar redes de contato e estabelecer relacionamentos com colegas no mundo todo
  • Reduzir ou até eliminar a necessidade de viajar enquanto permite a colaboração imediata e global nas empresas
  • Integrar tecnologias de ponta em áudio, vídeo e telefonia para ajudar as reuniões a serem realizadas de maneira tranquila


Download

NomeTamanhoMétodo de download
UnyteMeetingComponent.zip73KBHTTP

Informações sobre métodos de download


Recursos

Aprender

Obter produtos e tecnologias

Discutir

Sobre os autores

Stephen Wills é engenheiro de software e atua no Laboratório de Software de Dublin da IBM na Irlanda. Ele trabalha com o produto IBM Lotus Quickr, principalmente na área de elaboração de modelos. Entre em contato com Stephen através do e-mail stephen_wills@ie.ibm.com.

Ramajeyam Gopalraj é um Conselheiro de Engenharia de Software que trabalha com a equipe Lotus Quickr no Research Triangle Park, NC. Entre em contato com Ramajeyam através do e-mail ramajeyam_gopalraj@us.ibm.com.

Artur Grzenkowicz é engenheiro senior de software e trabalha no Laboratório de Software de Dublin da IBM na Irlanda. Ele trabalha com a Plataforma Java, na área de modelos do Enterprise Edition Lotus Quickr. Entre em contato com Artur através do e-mail agrzenko@ie.ibm.com.

Jon Brunn é o arquiteto do Lotus Quickr visando à integração com o Enterprise Content Management. No momento, Jon atua na linha do produto Lotus Quickr, principalmente nas áreas de ampliação, personalização e integração corporativa. Entre em contato com Jon através do e-mail jbrunn@us.ibm.com.

Ajuda para Relatar Abuso

Relatar abuso

Obrigado. Esta entrada foi sinalizada para atenção do moderador.


Ajuda para Relatar Abuso

Relatar abuso

Falha no envio do Relatório de abuso. Tente novamente mais tarde.


developerWorks: Registre-se


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Selecione seu nome de exibição

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.

(Deve possuir de 3 a 31 caracteres.)


Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Classificar este artigo

Comentários

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Lotus
ArticleID=413694
ArticleTitle=Criando um componente personalizado no IBM Lotus Quickr visando à integração com o IBM Lotus Sametime Unyte Meeting
publish-date=06302009
author1-email=stephen_wills@ie.ibm.com
author1-email-cc=
author2-email=ramajeyam_gopalraj@us.ibm.com
author2-email-cc=
author3-email=agrzenko@ie.ibm.com
author3-email-cc=
author4-email=jbrunn@us.ibm.com
author4-email-cc=

Conheça a IBM da sua cidade

Virtual Branch Office Brasil

A IBM está mais perto do que você imagina!


Tags

Help
Use o campo de pesquisa para encontrar todos os tipos de conteúdo no My developerWorks com essa tag.

Use a barra de rolagem para ver mais ou menos tags.

Tags populares mostra as principais tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Minhas tags mostra suas tags para esta zona de conteúdo em particular (por exemplo, Java technology, Linux, WebSphere).

Use o campo de pesquisa para localizar todos os tipos de conteúdo no Meu developerWorks com essa tag. Tags populares mostra as tags principais para essa zona de conteúdo particular (por exemplo, tecnologia Java, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere). Minhas tags mostra as suas tags para essa zona de conteúdo em particular (por exemplo, tecnologia Java, Linux, WebSphere).