\chapter{IMPLEMENTAÇÃO}

Neste capítulo descreve-se a metodologia de desenvolvimento adotada, bem como detalhes técnicos da implementação realizada.

Para a implementação deste projeto, os integrantes do grupo optaram por escrever todos os programas utilizando a linguagem Java. Essa foi a linguagem escolhida pelo fato dos membros do grupo já terem domínio dela, dela ser portátil e independente de sistema operacional, de ser largamente utilizada mundialmente, possuir muitas ferramentas e bibliotecas livres e possuir facilidade para desenvolver aplicações web.

\section{Metodologia de desenvolvimento}

Como proposto pela coordenação da disciplina, a estratégia geral de desenvolvimento foi de ter o primeiro semestre para estudos e especificação e o segundo semestre para a implementação.

Durante o primeiro semestre foi necessário empreender estudos relacionados ao domínio do nosso problema e avaliações de opções de tecnologias que poderiam ser empregadas.

Os estudos relacionados ao domínio do nosso problema eram basicamente os ligados à LIBRAS, em especial a notação SignWriting, e questões linguísticas, como o estudo feito sobre gramáticas transformativas.

Quanto às opções tecnológicas, foram estudos sobre bibliotecas e frameworks a serem utilizados, indo desde a parte gráfica, até o reconhecimento de categorias gramaticais.

Em bases desses estudos e avaliações pudemos descrever a especificação do sistema, que consistiu basicamente na arquitetura do sistema e função de cada um dos blocos, acompanhados já de uma análise de domínio, bem como considerações de requisitos funcionais e não-funcionais.

Durante o primeiro semestre, também antecipamos a construção do módulo do sintetizador de sinais em 3D, pois este foi desenvolvido como um projeto para a disciplina PCS2520 - Tecnologias de Computação Gráfica.

A metodologia de implementação para o segundo semestre foi a de construir os blocos especificados na arquitetura um de cada vez, ou seja, fazendo primeiro os blocos independentes, e deixando para o final os que dependiam dos blocos feitos anteriormente.

O fluxo de desenvolvimento, com as dependências (setas) evidenciadas, pode ser observado na figura \ref{fig:fluxo_dev}, na qual também se destaca o principal responsável pela implementação cada módulo (embora, deixemos claro, procurássemos fazer as atividades em conjunto, em especial às relacionadas a especificação e tomadas de decisão).

\begin{figure}[h]
  \centering
  \includegraphics[scale=0.45]{imagens/fluxo_dev.png}
  \caption{Fluxo de desenvolvimento}
  \label{fig:fluxo_dev}
\end{figure}

Obs: a posição horizontal de cada bloco na figura dá ideia de quando aquele bloco começou a ser implementado, porém na figura não está retratado quando o bloco foi finalizado, ou seja, o tempo de desenvolvimento gasto em cada um deles.

No entanto percebemos que uma metodologia mais iterativa poderia ter-nos valido mais, pois os blocos básicos apresentavam requisitos exigidos pelos blocos superiores que os usariam e sem começar a fazer antes os blocos superiores por vezes era difícil enxergar esses requisitos; assim um processo em que se fizessem aos poucos versões simplificadas de cada bloco poderia trazer um benefício maior para os blocos superiores e evitar retrabalho nos blocos inferiores.

Esse fluxo também trouxe o inconveniente de se super trabalhar alguns dos componentes inferiores, enquanto que os últimos acabaram sofrendo penalização por possuírem menos tempo de desenvolvimento, sendo esses últimos justamente os módulos responsáveis pelo processo de tradução, onde se aplica o estudo do domínio da LIBRAS.

Deixar esses módulos para o final não trouxe apenas o problema da escassez de tempo, mas também o fato de que caso os tivéssemos iniciados antecipadamente, poderíamos aproveitar melhor a ajuda de especialistas em LIBRAS que tínhamos a disposição (dúvidas respondidas sobre o domínio do problema mais no final do projeto são mais difícil de serem aproveitadas e incorporadas ao adequadamente ao projeto).

Sobre a metodologia de desenvolvimento cabe ainda comentar sobre o uso de tecnologias que auxiliaram o trabalho em grupo, notadamente o \emph{wiki} para construção colaborativa de documentos, o \emph{svn} para a construção colaborativa de código e a lista de e-mails para organização e arquivação de discussões; pode-se afirmar que o uso dessas tecnologias fazem uma grande diferença em termos de praticidade, evitando protocolos morosos e propensos a erros na relação entre os membros da equipe.

\section{Analisador Morfológico}

A solução elaborada para o analisador morfológico subsiste no uso da biblioteca JSpell. Como o presente projeto é desenvolvido em tecnologia  Java e o módulo JSpell, disponível apenas via código em linguagem C, o módulo implementador da interface analisador morfológico--sintático deve também lidar com módulos compilados em linguagem nativa (de máquina).

Para tanto, lança-se mão da Java Nat Interface (JNI)\footnotemark . Essa biblioteca permite que classes Java acessem códigos compilados para código de máquina. Porque as informações dos tipos primários de dados podem ser armazenadas distintamente na Java Virtual Machine e na estrutura nativa, faz-se necessário também que o código nativo utilize funções de conversão java--código nativo. 

\footnotetext{JNI. Disponível em \url{http://download.oracle.com/javase/1.4.2/docs/guide/jni/spec/functions.html}. Acesso em 06/12/2010}

Essas funções estão disponíveis ao código C através do cabeçalho \emph{jni.h}, disponível no diretório \emph{include} da JDK (\emph{Java Development Kit}). A fim de não se modificar o código original do JSpell, a integração com as funções de conversão citadas apenas podem ser utilizadas via outro módulo C. A este cabe a conversão de representação de tipos e o uso da biblioteca JSpell. Deve-se notar ainda que há, propriamente, certas idiossincrasias quanto à nomenclatura das funções e quando aos tipos a serem exportadas pelo módulo nativo ou passados a este como parâmetro. Para automatização dessa geração bem definida 
de nomes e parâmetros há um programa também disponível pela JDK, o \emph{javah}.

Esse programa recebe como parâmetro o caminho duma classe Java já compilada e identifica as funções dessa classe que devem ser providas por um módulo nativo, gerando o cabeçalho adequado para o desenvolvedor C. O procedimento é exemplificado abaixo:

\begin{enumerate}
\item Declaração, na classe Java, das funções naturais previstas:

\begin{verbatim}
private native String[] 
      consultWordPossibilities(String consultanda);
\end{verbatim}

\item Compilação da classe que usará a biblioteca nativa:

\verb!javac br/usp/language/morph/AnalisadorMorfologico.java!

\item Geração automática do cabeçalho nativo necessário:

\verb!javah -d jamori/ br.usp.language.morph.AnalisadorMorfologico!

Nota: acima, \verb!jamori/! é o diretório escolhido como destino do cabeçalho a se gerar.

Nome do cabeçalho gerado: \verb!br_usp_language_morph_AnalisadorMorfologico.h!

\item Inclusão, no arquivo \emph{jamori.c}, do cabeçalho para uso da biblioteca JSpell e do cabeçalho recém gerado:


\begin{verbatim}
#include <jslib.h>
#include "br_usp_language_morph_AnalisadorMorfologico.h"
\end{verbatim}

\end{enumerate}

\section{Analisador sintático}

\subsection*{Autômatos}

Foi criado primeiramente um modelo para autômatos para autômatos finitos. Nesse modelo, os símbolos de entrada devem ser sempre representados "Strings". 

Esse modelo foi incrementado para conter também ações (trechos de código) relacionadas às transições, i.e., o autômato vira um trandutor. A ação foi implementada através de uma interface (Action) com um único método (doAction()), e portanto, para adicionar uma ação ao autômato basta criar uma classe que implementa a interface.

Para utilizarmos autômatos para linguagens livres de contexto, o modelo foi estendido para um autômato de Pilha Estruturado (APE), cuja descrição pode ser encontrada na obra de \citeonline{jj2009}.

Assim sendo, foi adicionado o conceito de chamadas de submáquinas e de empilhamento de máquinas. Na definição original do APE determinístico, quando um estado possui uma chamada de submaquina, não deve possuir mais nenhuma outra transição, sendo portanto a chamada a transição obrigatória quando naquele estado. Para facilitar a construção da gramática e permitir maior flexibilidade, fizemos as seguintes modificações:

\begin{enumerate}
  \item É permitido que um estado possua transições "normais" e também chamadas de submáquina;
  \item É permitido que um estado possua mais de uma chamada de submáquina
  \item O estado pode ainda possuir transições epsilon
\end{enumerate}

Essas modificações trazem ao autômato algum não-determinismo nas suas decisões.
Para resolver os itens números 1 e 3, foi definida uma ordem de precedência implícita para as transições. Primeiro, a prioridade é para as chamadas de submáquina. Em seguida, as transições normais e se nenhuma for válida, a transição epsilon é escolhida. 

Para o item 2 foi implementado uma espécie de \emph{look-ahead} de estados, pesquisa-se em cada sub-maquina se ela possui uma transição para o símbolo de entrada atual. Se possuir, este é o escolhido. Esse \emph{look-ahead} é propagado se o estado inicial da máquina chamada possuir outras chamadas de sub-maquina ou transições epsilon.

Vejamos como exemplo um excerto da gramática que utilizamos para o português, baseada em \citeonline{luft2002}. Esse pedaço mostra as derivações de um sintagma substantivo (SS).

\begin{verbatim}
* SS -> PrAdj + NOME
* SS -> NOME
* SS -> *ppes*
* PrAdj -> *art*
* PrAdj -> *pdem*
* PrAdj -> *pind*
* PrAdj -> *ppos*
* NOME -> *nc*
* NOME -> *np*
\end{verbatim}

A partir dessa gramática, foi gerado o autômato de pilha estruturado da figura \ref{fig:sintatico_exemplo}. Vemos que ele tem uma relação direta com a gramática, é composto por 3 submáquinas: SS (a inicial), PrAdj e NOME, uma para cada não-terminal e cada transição representa um elemento das derivações.

\begin{figure}[h]
  \centering
  \includegraphics[scale=0.7]{imagens/sintatico_exemplo.png}
  \caption{Autômatos exemplo}
  \label{fig:sintatico_exemplo}
\end{figure}

Consideremos então a seguinte cadeia de entrada: ``art nc''. 

O estado inicial é S0 do SS. Vemos que ele possui 3 transições, sendo 2 chamadas de submáquina e 1 transição "normal". Conforme definido, a precedência é para as chamadas de submáquina. Mas existem 2 chamadas, então o autômato deve fazer um ``look-ahead'' em cada submaquina para ver se elas aceitariam o primeiro token ``art''. Vendo o estado inicial de NOME, vamos que ele não possui transição válida para ``art'', por outro lado PrAdj possui, portanto essa é a chamada escolhida. O estado de retorno de SS (S1) é empilhado e o autômato transita para a maquina PrAdj e consome o símbolo ``art'', transitando para o estado final.

O próximo símbolo da cadeia de entrada é ``nc (substantivo comum)''. Como a máquina já se encontra num estado de aceitação, o estado presente na pilha é desempilhado e a máquina passa para o estado S1 de SS. S1 só possui uma transição, então NOME é chamada, ``nc'' é consumido, retorna-se para SS e a máquina para no estado final de aceitação.

\subsection*{Funcionamento}

O analisador sintático então lê uma gramática definida pelo usuário e contrói um APE para ela. Ou seja, o usuário define um conjunto de regras gramaticais e o programa gera um reconhecedor da linguagem por elas descrita. Nas ações atribuídas para cada transição do autômato foram colocadas as operações de criação da árvore sintática. Basicamente, para cada novo não-terminal definido na gramática, um novo autômato finito é criado. E cada elemento gerado pela regra forma um novo estado neste mesmo autômato. Quando uma regra gramatical possui um não-terminal gerado, é colocada uma chamada de submáquina no autômato. Desse modo, o autômato de pilha estruturado é construído.

Quando o analisador opera, ele recebe um \emph{token} proveniente do analisador morfológico e usa a categoria (classe gramatical) dele para alimentar o autômato. Se ao final de todos os tokens de entrada o autômato se encontrar num estado de aceitação, a análise sintática ocorreu com sucesso. 

Quando há o caso do analisador morfológico devolver mais de uma possibilidade, o analisador sintático primeiro tenta com a primeira. Em caso de insucesso de consumo, a opção seguinte é a considerada.

A biblioteca para descrição e manipulação de árvores foi desenvolvida pelo grupo também, por não encontrarmos solução satisfatória no ``mercado''. 

\section{Transformador sintático}

Nessa seção detalhes da implementação do módulo do transformador sintático, especificado na seção~\ref{sec:ts}, serão apresentados. Como esse é o módulo que altera a estrutura sintática, ele principalmente realiza operações de árvores, utilizando extensivamente a biblioteca de árvores desenvolvida pelo grupo.

Um conjunto de regras foi definido para transformar a árvore do português na árvore da \libras com maior grau de fidelidade possível. Nesse presente trabalho as regras estão fixas por não termos chegado a uma conclusão satisfatória sobre qual seria o melhor formalismo para definir tais regras. Mas a ideia para trabalhos futuros, conforme descrito nos requisitos, é que essas regras possam ser definidas e modificadas dinamicamente, sem necessidade de recompilação do programa, com o intuito de ser possível sempre refinar a tradução, papel que deve ser exercido principalmente por linguistas das duas línguas em questão.

Dentre as funções listadas na especificação, neste trabalho não foram todas implementadas, deixando as demais para trabalhos futuros. Estão implementadas as funções de:

\begin{itemize}
\item Cortar elementos irrelevantes
\item Inserir advérbios 
\item Concordância verbal de pessoa e número
\item Escolha de ordem da sentença em alguns casos
\end{itemize}

Essas funções correspondem a uma implementação até o nível 3 da graduação proposta por esse trabalho na figura~\ref{fig:gradlibras_frase}.

Para implementar essas funções, os métodos usados nas árvores foram:

\begin{itemize}
\item Cortar elementos
\item Busca por folha mais próxima
\item Junção de elementos
\end{itemize}

A primeira função do transformador é simplesmente cortar elementos que não são relevantes para a língua-alvo. Tais elementos não carregam informações significativas para o entendimento da oração em \libras ou não fazem parte da estrutura dela. É o caso de preposições ou artigos, que não existem em \libras. Quando o programa encontra um nó da árvore que carrega um token com essas características, esse nó simplesmente é desligado do restante da árvore.

Outra função muito importante é a busca na árvore pela folha ``mais próxima" de uma outra folha. Por indefinições a respeito de qual seria a correta definição de distância nesse caso, por ora estamos utilizando uma heurística para resolver isso. A heurística consiste em simplesmente listar todas as folhas em ordem e retornar a mais próxima dentro dessa lista ordenada. Esse processo não é uma funcionalidade final do transformador sintático, mas sim um método de suporte a diversas funções.

Uma das funções que utilizam a busca de folha mais próxima como suporte é a junção de nós. Em LIBRAS, temos algumas classes de palavras que não possuem seu próprio sinal, mas elas modificam o sinal relacionado. Por exemplo, advérbios de modo como ``rapidamente" não são falados em \libras, mas modificam o jeito de expressar o sinal do verbo, aumentado a velocidade com que são feitos. Assim sendo, para que o verbo possua essa característica, as propriedades do nó ``advérbio" são inclusas nas do nó ``verbo" e o nó do advérbio é cortado, assim o nó do verbo conterá todas as informações necessárias para que o módulo contextualizador faça a modificação no sinal do verbo.

Sempre que o transformador encontra um nó que carrega um verbo, ele busca na árvore quem são o sujeito e o objeto dele para incorporar essas informações ao token do verbo, também para o contextualizador poder fazer a flexão verbal.

Então basicamente o transformador sintático varre a árvore nó por nó e dependendo do tipo de cada nó ele realiza ações que modificam a árvore. Esse processo está resumido na figura~\ref{fig:transf_sintatico}.

\begin{figure}[h]
  \centering
  \includegraphics[scale=0.8]{imagens/tranformador_impl.png}
  \caption{Funcionamento do transformador sintático}
  \label{fig:transf_sintatico}
\end{figure}

\section{Sintetizador de sinais 3D}

Este módulo, denominado \emph{Virtual Jonah} foi implementado em parceria com a aluna de design da FAU Heloisa Yoshioka em trabalho desenvolvido em contexto da disciplina PCS-2520 (Tecnologia de Computação Gráfica), ministrada pelo professor Ricardo Nakamura.

As tecnologias utilizadas acabaram sendo a API Processing, por já ser utilizada na disciplina e o 3DStudio para a modelagem, por ser uma ferramenta já dominada pela estudante de design, que criou os modelos.

O nome do trabalho (Virtual Jonah) foi inspirado no filme And Your Name Is Jonah, de 1979, que narra as dificuldades da vida de um menino surdo e sua família, incapazes de se comunicar entre sí, que apenas conseguem superar esse obstáculo quando o pai aprende Língua de Sinais.

A modelagem foi feita no 3D Studio Max, apesar de os modelos terem sido salvos no formato OBJ, que é um formato de modelos tridimensionais em formato texto, o que permite que ele seja facilmente interpretado por praticamente qualquer programa de modelagem.

No programa foram feitos dois modelos: o da mão, que serviu para gerar os .obj tanto da mão direita quanto da esquerda (eles são apenas espelhados) e o da cabeça. A principal diferença deles foi o fato de o modelo da mão ter bones e não ter textura e o da cabeça ter textura e não ter bones.

Mesmo que o formato .obj não suporte bones, o esqueleto da mão foi utilizado para definir mais facilmente as diferentes conformações dela, sendo que cada uma dessas posições é exportada com um .obj diferente.

\begin{figure}[h]
  \centering
  \includegraphics[scale=0.45]{imagens/jonah.png}
  \caption{Saída gráfica com o Virtual Jonah}
  \label{fig:jonah}
\end{figure}

A animação foi feita utilizando a biblioteca OBJ Loader~\footnotemark, responsável por carregar e renderizar os modelos no ambiente do Processing.

\footnotetext{OBJ Loader. Disponível em \url{<http://code.google.com/p/saitoobjloader/>}. Acesso em 06/12/2010}

Com a classe OBJModel da OBJ Loader pudemos carregar os modelos salvos em obj e manipular suas posições e orientações através dos comandos de deslocamento e de rotacionamento do Processing para que as mãos ficassem de acordo com o especificado no arquivo XML de entrada, que corresponde à discrição dos sinais discutida na seção Modelo de Dados.

Para que a mão pudesse mudar de configuração, a tática adotada foi herdar a classe OBJModel pela nossa classe AnimObj para criar novos métodos que pudessem determinar um outro modelo obj e executar o deslocamento de cada um dos vértices do obj original, através de interpolação linear, até que o modelo acabasse ficando idêntico ao novo obj especificado.

Para que essa técnica dê certo é importante que os vértices correspondentes listados no obj estejam descritos na mesma ordem em ambos os modelos.

Por considerarmos a classe AnimObj como algo útil, que inclusive poderia ser usado pelos próximos alunos da disciplina, acabamos por publicar essa classe de forma livre \footnotemark independentemente do resto do projeto.

\footnotetext{AnimObj. Disponível em \url{http://code.google.com/p/objanim/}. Acesso em 06/12/2010}

A criação da classe AnimObj e a relevância de sua disponibilização está numa interessante peculiaridade do Virtual Jonah: acontece que normalmente em jogos quando um personagem precisa realizar um movimento localizado, como abrir e fechar sua mão, este é um movimento pré-definido e usado com frequência, logo a solução nestes casos é, em tempo de modelagem, gerar animações dos movimentos da mão se abrindo ou fechando e carregar essa animações em tempo de execução; no nosso caso, as possibilidades de transição, de uma configuração de mão para outra, são tantas que tal técnica se torna inviável, e por isso é preciso a modificação do modelo em tempo de execução, seja pela manipulação dos \emph{bones}, seja pela manipulação da própria malha (\emph{mesh}), que é como é feito atualmente.

\section{Ferramenta colaborativa}

Inicialmente o WikiLibras começou a ser feito com base nas APIs de servlets Java EE e fazendo o acesso aos dados com a API JDBC, que é o que há de mais básico que há no mundo Java para aplicações web (básico no sentido de ser a tecnologia que serve de base para as outras mais avançadas).

Embora a inserção de sinal trate apenas de uma única entidade, essa mesma entidade é formada por uma composição de outras entidades (símbolos, mãos, movimentos e faces). Essa composição é na verdade um tanto quanto complexa, e fazer um único formulário para preencher esses dados, com estas tecnologias mais básicas, mostrou vários desafios (quebrar o formulário em várias telas também apresentava outros problemas nestas condições).

Além de inúmeros problemas que surgiam devido a detalhes da tecnologia, também havia o fato de que o uso de apenas essas ferramentas levava a uma ineficiência devido a grande repetição de código similares e burocráticos que era preciso escrever (\emph{boillerplate code}).

\begin{figure}[h]
  \centering
  \includegraphics[scale=0.6]{imagens/wikilibras.png}
  \caption{Tela de edição de sinal no WikiLibras}
  \label{fig:wikilibras}
\end{figure}

\subsection*{Ferramentas}

Devido às questões apresentadas procuramos utilizar frameworks que facilitassem o desenvolvimento dessa etapa do projeto, sendo o escolhido o VRaptor, que além de auxiliar no fluxo de navegação entre páginas e \emph{binds} entre parâmetros de formulários e objetos, também já trazia consigo o Hibernate, que realiza o mapeamento objeto-relacional para fazer conversões entre objetos e tabelas de banco de dados.

Assim, utilizando o Hibernate criou-se uma pequena classe que gerava automaticamente o banco de dados com base nas classes que modelavam os dados a serem salvos.

\begin{verbatim}
  public class GeraBanco {

      public static void main(String[] args) {
          Configuration conf = new AnnotationConfiguration();
          conf.configure();
          SchemaExport se = new SchemaExport(conf);
          se.create(true, true);
      }
  }
\end{verbatim}

Dado que o formulário é dividido em várias telas, criou-se também uma classe para armazenar os dados que estão sendo editados na sessão, a SignEditor, que possui os seguintes atributos:

\begin{verbatim}
    // sinal que está sendo criado/editado
    private Sign sign;
    // índice do símbolo sendo editado como é mostrado para o usuário 
    // na lista é acessado como signIndex-1
    private int signIndex = 1; 
    private HandSide side;
    private boolean twoHands = true;
    //indica se estamos editando um novo sinal
    private boolean newSign; 
\end{verbatim}

Para a interface usou-se páginas JSP, mas sem a escrita de \emph{scriptlets} (código Java embutido diretamente no HTML), em vez disso usou-se a \emph{expression language}, que consiste na escrita de variáveis definidas pelo servlet nas páginas HTML e no uso de bibliotecas de tags, a JSTL, para criar condições e laços na escrita de código HTML.

O uso dessas tags de bibliotecas poderia ser substituída pelo uso de tecnologias mais avançadas, como a JSF (Java Server Faces), que permite ao desenvolvedor escrever tags como se fossem elementos HTML mais sofisticados, no entanto nesse caso permanecemos com a tecnologia mais básica.

Como parte das tecnologias mais básica do mundo web também utilizamos o CSS para a formatação do estilo de apresentação do site, isto é, para definir seu layout e o Java Script para criar ações dinâmicas nos formulários quando necessário, a exemplificar: 

\begin{itemize}
\item adição de mais caixas de texto para entrada de palavras correspondentes;
\item alterar a foto de exibição ao se selecionar uma configuração de mão diferente;
\item restringir a lista de configurações de mão pela opção selecionada na lista de grupos de configurações de mão;
\end{itemize}

sendo que no último caso houve até mesmo uma interessante interação entre o código Java Script e as bibliotecas de tag JSTL.

\subsection*{Fotos}

Um aspecto bem importante para a facilidade de operação da interface foi a utilização de imagens representando cada uma das configurações de mão selecionadas.

Primeiro pesquisamos para saber se poderíamos usar algum conjunto de imagens prontas, mas não encontramos nadas disponível e prático de usar a mão, então acabamos optando por nós mesmo tirarmos fotos para representar as configurações.

Ao total foram 69 fotos, uma para cada configuração de mão, agrupadas em 10 grupos.

\subsection*{Codificação de caracteres}

Por vezes, em projetos como esse, acabamos por perder muito tempo em pequenos problemas que não eram previstos, o que em geral contribui para não precisão de estimativas na construção de sistemas de software.

Um desses casos que enfrentamos foi a dificuldade de lidar com a correta codificação de caracteres em determinados pontos do sistema. No caso do WikiLibras isso ocorreu quando devíamos gerar links que possuíssem como parâmetro o nome do sinal, que poderiam ter acentos.

Dessa forma, para permitir acentos nos nomes dos sinais, descobrimos que era necessário gerar as URLs com o comando \verb!URLEncoder.encode(link, "ISO-8859-1")!.

\subsection*{Ambiente de execução}

Para deixar o WikiLibras disponível na Internet, a fim de contar com a colaboração de outras pessoas para criar o vocabulário a ser usado em nosso tradutor, conseguimos o apoio do projeto Poli Cidadã, que permitiu-nos hospedar o WikiLibras sem seu servidor.

No servidor disponibilizado havia um servidor Apache instalado, mas não o container Tomcat, que é responsável por executar o código Java e gerar as páginas HTML a partir desse processamento.

Uma vez cedido o servidor, a responsabilidade de efetuar toda a configuração necessária era nossa. 

Após instalar o Tomcat (que é basicamente descompactar o Tomcat em qualquer lugar) o primeiro foi preciso encontrar uma porta de conexão disponível; mas mesmo após encontrarmos essa porta, vimos que só podíamos acessar a aplicação instalada no Tomcat pelo localhost (aliás, como o acesso ao servidor era feito via \emph{ssh}, esses testes eram realizados com o navegador modo-texto \emph{lynx}).

Dada as restrições de seguranças de configurações de porta, decidimos que o jeito certo de tornar a aplicação disponível seria fazer a ponte entre a requisição e o Tomcat através do Apache, ou seja, o Apache recebe a requisição e encaminha para o Tomcat executar o processamento; essa técnica é na verdade o modo correto de se fazer isso mesmo sem considerar as restrições das portas, pois desejamos que o usuário acesse a página \emph{http://www.policidada.poli.usp.br/wikilibras}, e não algo como \newline \emph{http://www.policidada.poli.usp.br:8081/wikilibras}.

A primeira forma encontrada para fazer isso foi baseada em páginas de documentação do próprio Tomcat \footnotemark.

\footnotetext{The Apache Tomcat Connector - Generic HowTo: \url{<http://tomcat.apache.org/connectors-doc/generic_howto/workers.html>}. Acesso em 06/12/2010}


O Tomcat quando iniciado, já deixa uma porta aberta para comunicações pelo protocolo \emph{AJP}, que é uma versão otimizada do protocolo HTTP para a comunicação do Tomcat com outros web servers. A ideia então era fazer com que o Apache se conectasse a esse serviço AJP do Tomcat.

Seguindo o site, baixamos o módulo do Apache para que isso funcionasse: o \emph{mod\_jk}; também criamos um arquivo de configuração (workers.properties) e adicionamos algumas linhas ao arquivo de configuração do Apache (apache2.conf).

Esse procedimento funcionou com sucesso em uma de nossas máquinas pessoais, mas no servidor não funcionou. Nem o acesso em localhost à aplicação pelo Tomcat funcionava.

Depois de gastar algum tempo investigando a situação, não obtivemos sucesso e recorremos a um fórum para pedir ajuda (utilizamos o GUJ, fórum brasileiro para desenvolvedores Java).

O post se encontra em: http://www.guj.com.br/posts/list/221913.java

Obtivemos uma resposta que nos indicava para utilizar outro módulo do apache para fazer isso: o \emph{mod\_proxy\_ajp} (que por sua vez depende do \emph{mod\_proxy}).

Seguimos então o procedimento que foi muito mais simples: uma vez que os módulos necessários já se encontravam instalados no Apache, bastou acrescentar as seguintes linhas ao apache2.conf:

\begin{verbatim}
      # Enable Tomcat to work with Apache
      ProxyPass  /WikiLibras ajp://localhost:8009/WikiLibras
      LoadModule proxy_module 
      			/usr/lib/apache2/modules/mod_proxy.so
      LoadModule proxy_ajp_module 
      			/usr/lib/apache2/modules/mod_proxy_ajp.so
\end{verbatim}

Obs: 8009 é a porta utilizada pelo Tomcat para a comunicação AJP.


\section{Dicionário}

A camada de WebService feita no WikiLibras, responsável por disponibilizar a base de conhecimento construída, consiste no lado servidor do dicionário.

Para realizar a implementação deste componente o primeiro passo foi estudar os conceitos de WebServices, que podemos resumir rapidamente aqui:

\begin{itemize}
\item XML (Extensible Markup Language): linguagem de descrição de dados flexível em formato texto padronizada pela W3C (World Wide Web Consortium);
\item SOAP (simple object access protocol): \emph{envelope} com a estrutura da mensagem enviada pelo WebService; 
\item WSDL (web services description language): arquivo XML que descreve a interface pública do WebService para que outros softwares possam utilizar seus serviços; a descrição contem as funções disponíveis e os tipos de dados envolvidos;
\item UDDI (universal description, discovery and integration): repositório de WebServices para que serviços possam ser encontrados de forma automática (não utilizado neste trabalho).
\end{itemize}

Após entendido os conceitos, era preciso escolher qual framework usar. Esse passo é particularmente complexo devido a variedade de informações e a rápida evolução das ferramentas, de forma que o que usamos há um ano atrás para fazer web services já não é a melhor ferramenta no momento.

O framework escolhido foi o \emph{JAX-WS} (Java API for XML Web Services), que é a solução aberta mais moderna no mundo Java para WebServices, sendo que os mesmos podem ser facilmente criados através do uso de \emph{anotações} nos métodos que devem ser publicados.

Dessa forma os passos necessários para a criação do WebService foram os seguintes:

\subsection*{1 - Criação da interface}

Neste passo o importante é o uso correto das anotações (\emph{tokens} precedidos pelo "@").

\begin{verbatim}
     import javax.jws.WebMethod;
     import javax.jws.WebService;

     @WebService
     public interface ISignDictionaryWS {
    
         @WebMethod
         public Sign signByName(String name);

         @WebMethod    
         public List<Sign> nearSigns(String name);
    
         @WebMethod
         public List<Sign> translate(String word);
    
         @WebMethod
         public Sign simpleTranslate(String word);
     }
\end{verbatim}

\subsection*{2 - Implementação da classe}

Feito com a classe SignDictionaryWS (que, obviamente, implementa ISignDictionary).

A princípio implementar cada um desses métodos é fácil dado que temos um objeto \emph{signDao}, que é responsável pelo acesso ao banco de dados, já fazendo o mapeamento objeto-relacional utilizando o Hibernate.

A única parte mais complicada deste código é o procedimento para obter o DAO através de uma sessão do Hibernate, que é feito pelo seguinte trecho código.

\begin{verbatim}
// obtendo o dao que acessa o banco de dados pelo Hibernate
SessionFactory sessions = 
   new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sessions.openSession();        
SignDaoFactory<Sign> factory = 
   new SignDaoFactory<Sign>(session);
this.dao = factory.getSignDao();
\end{verbatim}


Obs: este procedimento não é necessário na maior parte do WikiLibras, pois a sessão do Hibernate é fornecida "pronta" pelo framework VRaptor.

\subsection*{3 - Arquivos de configuração}

Foi necessário criar o arquivo WEB-INF/sun-jaxws.xml:

\begin{verbatim}
<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns='
    http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
    <endpoint
     name='signws'
     implementation='br.usp.wikilibras.ws.SignDictionaryWS'
     url-pattern='/ws/dictionary'
    />
</endpoints>
\end{verbatim}

Também foi necessário adicionar as seguintes linhas ao WEB-INF/web.xml:

\begin{verbatim}
<listener>
  <listener-class>
    com.sun.xml.ws.transport.http.servlet.WSServletContextListener
  </listener-class>
</listener>
  <servlet>
    <description>Dicionário JAXWS</description>
	<display-name>signws</display-name>
    <servlet-name>signws</servlet-name>
	<servlet-class>
	  com.sun.xml.ws.transport.http.servlet.WSServlet
	</servlet-class>
	<load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
     <servlet-name>signws</servlet-name>
     <url-pattern>/ws/dictionary</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>60</session-timeout>
  </session-config>
\end{verbatim}

\subsection*{4 - Gerando o WSDL e demais arquivos}

Uma vez que os passos anteriores foram seguidos, basta iniciar o Tomcat que o JAX-WS se encarregará de criar o arquivo WSDL.xml e demais classes que forem necessárias para o WebService funcionar (essas classes criadas automaticamente nem aparecem em nossa estrutura de projeto).

Para ver se está tudo funcionando, basta acessar pelo navegador \newline `http://localhost:8081/wikilibras/ws/dictionary?wsdl`, onde 8081 é a porta do Tomcat. Se o arquivo xml aparecer no navegador, o WebService está pronto para uso!

\subsection*{Cliente WebService}

Enquanto o WebService foi implementado no projeto WikiLibras, o lado cliente foi implementado no projeto PoliLibras, que é onde está o tradutor (do ponto de vista da organização no Eclipse, são projetos totalmente distintos, sem dependências).

Para criar o cliente, o primeiro passo é executar o seguinte comando (o prompt deve se localizar no diretório raiz do projeto):

\begin{verbatim}
$> wsimport -d src -s src 
     http://localhost:8081/wikilibras/ws/dictionary?wsdl
\end{verbatim}

Esse comando irá ler a descrição do WSDL e criar as classes necessárias para que os métodos do WebService possam ser acessados do projeto cliente. Dentre as classes geradas, está a interface ISignDictionaryWS (note que a implementação não aparece para o cliente, pois a ideia de WebService é a invocação da implementação no servidor).

Todas as classes e interfaces geradas apareceram num novo pacote dentro do projeto (wikilibras.ws).

A forma de se utilizar os métodos do dicionário então é:

\begin{verbatim}
  SignDictionaryWSService service = new SignDictionaryWSService();
  ISignDictionaryWS dictionary = service.getSignDictionaryWSPort();
\end{verbatim}

Dessa forma utilizar o objeto dictionary criado será a mesma coisa que usar um objeto SignDictionaryWS.

Mas criou-se ainda uma classe WikiLibrasDictionary (implementando uma interface SignDictionary, idêntica à interface ISignDictionary do servidor) no projeto cliente, que é responsável por executar as linhas acima e redirecionar as chamadas para o WebService. O propósito principal é fazer com que as outras partes do projeto (cliente) que queiram utilizar o dicionário, utilizem apenas uma classe simples, sem precisar saber que estão usando WebServices ou qualquer outra coisa.  

Uma facilidade acrescentada foi fazer com que o cliente pudesse facilmente trocar a localização do WebService; isso foi feito para garantir que em caso de falta de conectividade, poderíamos utilizar o WebService em localhost. Isso foi feito criando um arquivo de configuração no projeto (conf/polilibras.conf) que seta o caminho do WSDL a ser utilizado e alterando-se uma das classes geradas automaticamente (a SignDictionaryWSService) para utilizar esse valor em vez do \emph{default hard-coded}.

Um outro bom motivo para criar essa classe de isolamento (WikiLibrasDictionary) foi isolar as classes de domínio originais do projeto das classes do domínio que são repetidas e geradas automaticamente pelo WebService, que acabam parando no pacote wikilibras.ws no projeto do cliente, sendo que essas classes geradas automaticamente perdem a hierarquia de pacotes original das classes do modelo, ou seja, embora "idênticas" as classes retornadas por ISignDictionaryWS no cliente não são as mesmas classes de domínio utilizadas no resto do projeto (que estão no pacote libras.sign).

Dessa forma, WikiLibrasDictionary utiliza a classe ClassConverter para retornar ao usuário (no projeto do tradutor) as classes de domínio do pacote libras.sign, facilitando seu uso.

\section{Contextualizador}

Consoante desenvolvido na especificação, vários aspectos do contextualizador se encontram no estilo \emph{hard-coded}. Por carência de cadastro de sinais ou mesmo da própria compreensão da língua alvo, \libras, não se obteve muita generalização para este módulo. De fato, é o mais dependente da língua alvo, envolvendo entendimento desde a semântica até a morfologia, passando pela sintaxe.

Outras adaptações e ideias de como obtê-las podem ser vistas na sessão sobre trabalhos futuros.

\section{Organização dos repositórios}

Como mencionado, desejamos uma divisão modular do nosso sistema, de forma que os módulos possam ser reaproveitados independentemente em outros sistemas. Mas conforme discutiremos, realizar essa divisão não é tão trivial.

A não trivialidade depende basicamente de conceber dois cenários: o primeiro em que nosso sistema está em constante desenvolvimento, sendo todos os módulo atualizados constantemente em paralelo e um segundo cenário posterior, em que os módulos estão mais estáveis e recebem menos atualizações.

Considerando o cenário estável concebemos a seguinte divisão:

\begin{itemize}
\item classes que modelam os sinais
\item animobj 
\item virtual jonah 
\item wiki-libras 
\item bosque (biblioteca de árvores)
\item jjspell 
\item analisador sintático 
\item tradutor enquanto api 
\item tradutor com interface web 
\end{itemize}

Essa divisão corresponde a diferentes repositórios que permitam um desenvolvimento independente dos módulo.
 
No entanto há as relações de dependência, a exemplo do analisador sintático, que depende do analisador morfológico (o JJSpel). Em um ambiente estável uma atualização do jjspel não implicaria a automática atualização de seu uso no analisador sintático, seria necessário que no repositório do analisador sintático se decidisse por atualizar a versão utilizada do jjspel.

Esse tipo de procedimento é bem inconveniente no cenário inicial de desenvolvimento, pois quando estamos desenvolvendo a versão inicial que acaba por integrar todos os módulos, é desejável que todos os módulos utilizem a versão mais recente dos módulos dos quais dependem.

Em especial, há uma complexidade especial no módulo do conjunto de classes do domínio, pois além de ser usada em vários módulos, acabou por sofrer uma diferenciação por receber um atributo \emph{id} e \emph{anotações} para permitir que as classes fossem utilizadas pelo Hibernate. Na verdade, nesse caso o ideal seria substituir as anotações por uma descrição do mapeamento objeto-relacional por arquivo XML denominado ORM, uma vez que tais anotações não fazem sentido nos outros módulos.

Considerando então esses aspectos, decidimos por adotar uma estrutura de repositórios durante o desenvolvimento que fosse mais conveniente e pretendemos após a conclusão do projeto enquanto trabalho de conclusão de curso alterar a estrutura dos repositórios para a estrutura já apresentada, condizente com o cenário posterior.

A atual estrutura de repositórios consiste em três divisões:

\begin{itemize}
\item Projeto Java que engloba as classes de modelagem dos sinais, o jjspel, o bosque, o analisador sintático, o virtual jonah e o tradutor em si enquanto API, que consiste nos módulos transformador sintático, dicionário e contextualizador;
\item Projeto Java EE para o WikiLibras, que repete as classes de domínio, mas com as anotações; neste projeto está basicamente a aplicação web do WikiLibras e seu WebService;
\item Projeto Java EE do tradutor, que consiste na interface web do tradutor, que utiliza o Virtual Jonah e o tradutor enquanto API.
\item Mais um repositório extra já criado para a classe AnimObj, responsável por criar animações com modelos OBJ.
\end{itemize}




