I – Introdução

 

Todos que trabalham com informática, e neste caso me dirijo principalmente aos profissionais

que lidam com Sistemas de Gerenciamento de Banco de Dados(SGBDS), sabem  da existência

de centenas de funções úteis nos SGBDS que gostaríamos de utilizar, mas que por terem sido concebidas para outros países, com língua e sistemas métricos diferentes, se mostram inviáveis para utilização no nosso ambiente operacional.  Uma maneira muito interessante de tratar essa limitação, existente na maioria dos SGBDS, é lançarmos mão da criação de nossas próprias funções, adequando-as ao nosso ambiente e necessidades. Vamos exemplificar esse procedimento com a criação de um procedimento armazenado em Java seu acesso como uma função pública no SGBD Oracle.

 

Por que implementar a função no SGBD e não na aplicação?  Confesso que esta discussão esta muito em pauta e, que  coloca muitas vezes os administradores de Banco de Dados em conflito com os Desenvolvedores de Aplicação, na minha modesta opinião o assunto deve ser tratado caso a caso com a devida isenção técnica levando em conta vários fatores que podem pesar pela opção do SGBD, tais como:

 

·         A natureza da organização – para grandes Organizações, como Bancos Comerciais, seu maior patrimônio são os dados e pelo porte de suas organizações a mudança de SGBD não é uma opção constante, conheço organizações que trabalham a

    mais de 10 anos com o mesmo SGBD e todos os seus projetos para daqui a 5 anos incluem o mesmo SGBD. Neste caso a independência da aplicação com relação ao SGBD não é fator chave, inclusive a sugestão de alteração do SGBD por parte de desenvolvedores externos é visto com muitas reservas. Nestes casos o cliente espera justamente o contrário, que se obtenha o máximo de seu SGBD, valorizando seu investimento, que não é pequeno.

 

·         Muitas organizações com SGBD centralizado, Federado ou não, e que possuem ambiente de desenvolvimento e produção muito heterogêneos, com base de dados única optam pela centralização das regras de negócio no SGBD para evitarem os risco de perda da “inteligência “ da sua atividade e fortalecer a padronização sobre os diversos aplicativos que executam em  paralelo. Dessa forma uma aplicações diferentes (Delphi-client-server, .NET ou Java) realizam exatamente o mesmo procedimento padronizado no Banco de Dados. Ao mesmo tempo em que o cliente domina a “inteligência” de seu negócio ele impõe uma padronização aos seus desenvolvedores, sem se utilizar de Servidores de Aplicação ou protocolos criados para essa finalidade.

 

      

Não estou querendo afirmar que sempre se devam criar as funções no SGBD, não se deve, mas que sempre se deve proceder à análise da melhor alternativa para cada caso.

 

I I – Função para busca fonética em Português

 

Um problema comum na localização de registros, principalmente nomes próprios, vem da maneira como palavras pronunciadas da mesma maneira possuem diversas grafias, por exemplo Rafael e Raphael, Valter  e Walter, etc.. que tem exatamente a mesma pronuncia, mas que possuem grafias diferentes o que torna a  busca com operadores relacionais e funções, como  “like”, ineficientes em muitos casos. Para a língua Inglesa existe, em diversos sistemas, a função Soundex (para maiores detalhes procure a documentação do seu SGBD e caso queira conhecer um pouco mais sobre este algoritmo uma ótima referência é ART OF COMPUTER PROGRAMMING - V.3 SORTING AND SEARCHING,  KNUTH, DONALD ERVIN).

 

Antes de entrar na função propriamente dita, abrimos um parêntese, existem diversas abordagens a esse problema, como por exemplo: A função deve ser inserida no banco ou aplicativo?, Como proceder a fonetização?(devemos fonetizar o nome completo ou cada parte do mesmo?) Existe um modelo que maximiza a eficiência do algoritmo?. Estas questões extrapolam o escopo desse pequeno artigo no qual vamos nos concentrar com a função de fonetização, sua implementação no banco de dados e sua utilização fazendo às vezes da função “soundex”. Só para deixar registro existe um alfabético fonético internacional, já reparou nos caracteres “esquisitos” de seu dicionário inglês-português?, infelizmente os lingüistas de língua portuguesa não se deram, ainda, a importância que seria  a existência de padronização fonética em caracteres da língua portuguesa para a informática,  isso quer dizer que em virtude de diferenças nestes algoritmos podemos ter diferenças de resultados, mas este é um assunto para outro momento,  e um dos motivos que podem servir de justificativa para que a função fique centralizada no SGBD.   

 

 

I I I– Procedimento Java Armazenado

 

Como citado anteriormente iremos construir nossa função tomando como base procedimentos armazenados em Java, se possível leia novamente as edições 4  e 5 da SQLMagazine.

        

A decisão de se usar procedimentos armazenados em Java no Oracle, e não uma linguagem como C/C++, é que os mesmos são executados originalmente no JVM do Oracle no espaço de endereço do banco de dados, com isso temos menor número de trocas de contexto entre processos ao nível de sistema operacional ao mesmo tempo em que o código Java esta sempre executando como “proprietário do software Oracle”, detalhe o Oracle possui uma JDK embutido, Oracle9i - jdk 1.3 e o 10g - jdk 1.4 ambos Aurora. Para este exemplo utilizamos o Oracle 9i, creio que o mesmo funcionará sem maiores problemas para o Oracle 10G, porém não é possível implementar esses procedimento no Oracle Express Edition(XE) pois o mesmo não possui suporte para tal.

 

Neste exemplo iremos montar nossa classe Java fonetizar com a utilização do comando

CREATE JAVA, este comando cria um objeto contendo um fonte de código Java ou uma Classe(maiores detalhes Oracle9i – SQL Reference – a96540.pdf) o comando utilizado terá a seguinte sintaxe:

 

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "Fonetica"  As ...

 

O fonte da função de fonetização em Java, para a língua portuguesa que iremos utilizar é a disponibilizada pelo Instituto do Coração da Faculdade de Medicina da Universidade de São Paulo, que desenvolveu alguns componentes de fonetização em Java com suporte CORBA e está disponibilizando-os com código fonte aberto
(licença GNU) no Consórcio de Componentes de Software para Sistemas de Informação em Saúde (CCS-SIS). Estes componentes de fonetização foram utilizados na implementação do Serviço de Identificação de Pacientes (PIDS) e estão disponíveis em : http://www.incor.usp.br/spdweb/ccssis/fonetica/.

 

Visando simplificar a sua utilização usamos,  apenas um pequeno fragmento desse pacote, mas fortemente indico a todos que o estudem por completo.

 

O Comando com o algoritmo Java completo está na listagem 1(anexos).

 

 

I V – Procedimento Java Armazenado

        

Uma vez criada a classe temos que a tornar acessível para nossos usuários, isso se dá  com a criação de uma função, obs.: Lembro que são necessárias as permissões e privilégios para a realização dessas tarefas.

 

CREATE OR REPLACE FUNCTION FONETIZAR (str VARCHAR) RETURN VARCHAR

AS LANGUAGE JAVA NAME 'Fonetica.fonetizar(java.lang.String) return java.lang.String';

 

Por fim agora podemos criar um sinônimo público para tornar disponível a todos os usuários do nosso banco a função que acabamos de criar.

 

CREATE PUBLIC SYNONYM FONETIZAR FOR FONETIZAR;

        

Neste momento podemos testar nossa função, imaginado uma  tabela FUNCIONARIO , com o campo nome (varchar) a pesquisa poderia ser feita da seguinte forma:

 

     SELECT NOME, CPF FROM FUNCIONARIOS

     WHERE

     FONETIZAR(NOME)=FONETIZAR(“RAPHAEL”)

 

Poderíamos obter como resultado tanto o funcionário “RAPHAEL” como “RAFAEL”, uma outra customização possível seria a construção de uma tabela com os nomes “fonetizados” juntamente com um índice para a tabela FUNCIONARIO, com isso pode-se realizar uma busca mais rápida e com “fragmentos” do nome, poderíamos ter como retorno LUIZ RAPHAEL ou ROBERTO RAFAEL, juntamente com os resultados já retornados.

 

Espero que tenham gostado, e até a próxima.                      

 


V - Anexos

 

Listagem 1

 

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "Fonetica" AS

import java.util.*;

public class Fonetica {       

 public static String fonetizar (String str) {

    //Fonetiza o string recebido como parametro e devolve

    //um outro string (que e o primeiro fonetizado)

 

    str = str.toUpperCase(); //todas as letras maiusculas

    str = removePrep(str); //remove as preposições

    str = removeAccentuation(str); //remove os acentos

    str = removeStrange(str); //remove caracteres diferentes de

                                              // A-Z, 0-9

    str = fonetize(str); //fonetiza o texto

    return str;

    }   

 

         public static String fonetize (String str) {

                   //Função que faz efetivamente a substituição de letras,

                   //fonetizando o texto

                  

                   //matrizes de caracteres utilizadas para manipular o texto

                   char[] foncmp = new char[256];

                  char[] fonwrk = new char[256];

                   char[] fonaux = new char[256];

                   char[] fonfon = new char[256];

       

                   int i, j, x, k, //contadores

                       desloc, //posicao atual no vetor

                            endfon, //indica se eh ultimo fonema

                            copfon, //indica se o fonema deve ser copiado

                            copmud, newmud; //indica se o fonema eh mudo

                  

                   //Vetor utilizado para armazenar o texto:

                   //cada palavra do texto e armazenada em uma posicao do vetor

                   Vector component = new Vector();

                  

                   i = 0;

                   j = 0;//zera os contadores

 

                   str = removeMultiple(str);

                   //todos os caracteres duplicados sao eliminados

                //exemplo: SS -> S, RR -> R

 

         component = strToVector(str);

         //o texto eh armazenado no vetor:

         //cada palavra ocupa uma posicao do vetor

 

 

         for (desloc = 0; desloc < component.size(); desloc ++) {

         //percorre o vetor, palavra a palavra

 

           for (i = 0; i < 256; i++) {

             fonwrk[i] = ' ';

             fonfon[i] = ' ';//branqueia as matrizes

           }//for

 

           foncmp = component.elementAt(desloc).toString().toCharArray();

           fonaux = foncmp;

           //matrizes recebem os caracteres da palavra atual

 

           j = 0;

 

           if (component.elementAt(desloc).toString().length() == 1) {

             fonwrk[0] = foncmp[0];

           //se a palavra possuir apenas 1 caracter, nao altera a palavra

 

             if (foncmp[0] == '_') {

               fonwrk[0] = ' ';

             //se o caracter for "_", troca por espaco em branco

 

             }//if

             else

               if ((foncmp[0] == 'E')||

                   (foncmp[0] == '&')||

                   (foncmp[0] == 'I')) {

                 fonwrk[0] = 'i';

                 //se o caracter for "E", "&" ou "I", troca por "i"

 

               }//if

           }//if

           else {

             for (i = 0; i < component.elementAt(desloc).toString().length(); i++)

             //percorre a palavra corrente, caracter a caracter

 

               if (foncmp[i] == '_')

                 fonfon[i] = 'Y';     // _ -> Y

               else

                 if (foncmp[i] == '&')

                   fonfon[i] = 'i';     //& -> i

                 else

                   if ((foncmp[i] == 'E') ||

                       (foncmp[i] == 'Y') ||

                       (foncmp[i] == 'I'))

                     fonfon[i] = 'i';     // E, Y, I -> i

                   else

                     if ((foncmp[i] == 'O') ||

                         (foncmp[i] == 'U'))

                       fonfon[i] = 'o';     // O, U -> u

                     else

                       if (foncmp[i] == 'A')

                         fonfon[i] = 'a';      // A -> a

                       else

                         if (foncmp[i] == 'S')

                           fonfon[i] = 's';     // S -> s

                         else

                           fonfon[i] = foncmp[i];

                           //caracter nao eh modificado

 

             endfon = 0;

             fonaux = fonfon;

 

             //palavras formadas por apenas 3 consoantes

             //sao dispensadas do processo de fonetizacao

             if (fonaux[3] == ' ')

               if ((fonaux[0] == 'a') ||

                   (fonaux[0] == 'i') ||

                   (fonaux[0] == 'o'))

                 endfon = 0;

               else

                 if ((fonaux[1] == 'a') ||

                     (fonaux[1] == 'i') ||

                     (fonaux[1] == 'o'))

                   endfon = 0;

                 else

                   if ((fonaux[2] == 'a') ||

                       (fonaux[2] == 'i') ||

                       (fonaux[2] == 'o'))

                     endfon = 0;

                   else {

                     endfon = 1;

                     fonwrk[0] = fonaux[0];

                     fonwrk[1] = fonaux [1];

                     fonwrk[2] = fonaux [2];

                   }//else

 

             if (endfon != 1) { //se a palavra nao for formada por apenas 3 consoantes...

               for (i = 0; i < component.elementAt(desloc).toString().length(); i++) {

               //percorre a palavra corrente, letra a letra

 

                 copfon = 0;

                 copmud = 0;

                 newmud = 0;

                 //zera variaveis de controle

 

                 switch (fonaux[i]) {

 

                   case 'a':  //se o caracter for a

 

                     //se a palavra termina com As, AZ, AM, ou AN,

                     //elimina a consoante do final da palavra

                     if ((fonaux[i+1]== 's') ||

                         (fonaux[i+1]== 'Z') ||

                         (fonaux[i+1]== 'M') ||

                         (fonaux[i+1]== 'N'))

                       if(fonaux[i+2]!= ' ')

                         copfon = 1;

                       else {

                         fonwrk[j] = 'a';

                         fonwrk[j+1] = ' ';

                         j++;

                         i++;

                       }//else

                     else copfon = 1;

                   break;

 

                   case 'B':  //se o caracter for B

 

                     // B nao eh modificado

                     copmud = 1;

                   break;

 

                   case 'C':  //se o caracter for C

 

                     x = 0;

                     if (fonaux[i+1] == 'i')

 

                     //ci vira si

                     { fonwrk[j] = 's';

                       j++;

                       break;

                     }//if

 

                     //coes final vira cao

                     if ((fonaux[i+1] == 'o') &&

                         (fonaux[i+2] == 'i') &&

                         (fonaux[i+3] == 's') &&

                         (fonaux[i+4] == ' '))

                     { fonwrk[j] = 'K';

                       fonwrk[j+1] = 'a';

                       fonwrk[j+2] = 'o';

                       i = i + 4;

                       break;

                     }//if

 

                     //ct vira t

                     if (fonaux[i+1] == 'T')

                       break;

 

                     //   c vira k

                     if (fonaux[i+1] != 'H')

                     { fonwrk[j] = 'K';

                       newmud = 1;

 

                       //   ck vira k

                       if (fonaux[i+1] == 'K')

                       { i++;

                         break;

                       }//if

 

                       else break;

                     }//if

 

                     //ch vira k para chi final, chi vogal, chini final e

                     //chiti final

 

                     //chi final ou chi vogal

                     if (fonaux[i+1] == 'H')

                       if (fonaux[i+2] == 'i')

                         if ((fonaux[i+3] == 'a')||

                             (fonaux[i+3] == 'i')||

                             (fonaux[i+3] == 'o'))

                           x = 1;

 

                     // chini final

                     else

                       if (fonaux[i+3] == 'N')

                         if (fonaux[i+4] == 'i')

                           if (fonaux[i+5] == ' ')

                             x = 1;

 

                           else;

                         else;

                       else

                         // chiti final

                         if (fonaux[i+3] == 'T')

                           if (fonaux[i+4] == 'i')

                             if (fonaux[i+5] == ' ')

                               x = 1;

                     if (x == 1)

                     { fonwrk[j] = 'K';

                       j++;

                       i++;

                       break;

                     }//if

 

                   //chi, nao chi final, chi vogal, chini final ou chiti final

                   //ch nao seguido de i

                   //se anterior nao e s, ch = x

                   if (j > 0)

 

                     //sch: fonema recua uma posicao

                     if (fonwrk[j-1] == 's')

                       { j--;

                       }//if

                     fonwrk[j] = 'X';

                     newmud = 1;

                     i++;

                   break;

 

                   case 'D':  //se o caracter for D

                     x = 0;

 

                     //procura por dor

                     if (fonaux[i+1] != 'o')

                     { copmud = 1;

                       break;

                     }//if

                     else

                       if (fonaux[i+2] == 'R')

                         if (i != 0)

                           x = 1; // dor nao inicial

                         else copfon = 1; // dor inicial

                       else copfon = 1;  // nao e dor

                     if (x == 1)

                       if (fonaux[i+3] == 'i')

                         if (fonaux[i+4] == 's') // dores

                           if (fonaux[i+5] != ' ')

                             x = 0;  // nao e dores

                           else;

                         else x = 0;

                       else

                         if (fonaux[i+3] == 'a')

                           if (fonaux[i+4] != ' ')

                             if (fonaux[i+4] != 's')

                               x = 0;

                             else

                               if (fonaux[i+5] != ' ')

                                 x = 0;

                               else;

                           else;

                         else x = 0;

                     else x = 0;

                     if (x == 1)

                     { fonwrk[j] = 'D';

                       fonwrk[j+1] = 'o';

                       fonwrk[j+2] = 'R';

                       i = i + 5;

                     }//if

                     else copfon = 1;

                   break;

 

                   case 'F':  //se o caracter for F

 

                     //F nao eh modificado

                     copmud = 1;

                   break;

 

                   case 'G':  //se o caracter for G

 

                     //gui -> gi

                     if (fonaux[i+1] == 'o')

                       if (fonaux[i+2] == 'i')

                       { fonwrk[j] = 'G';

                         fonwrk[j+1] = 'i';

                         j += 2;

                         i +=2;

                       }//if

                       //diferente de gui copia como consoante muda

                       else copmud = 1;

                     else

 

                       //gl

                       if (fonaux[i+1] == 'L')

                         if (fonaux[i+2] == 'i')

 

                           //gli + vogal -> li + vogal

                           if ((fonaux[i+3]=='a')||

                               (fonaux[i+3]=='i')||

                               (fonaux[i+3]=='o'))

                           { fonwrk[j] = fonaux[i+1];

                             fonwrk[j+1] = fonaux[i+2];

                             j += 2;

                             i += 2;

                           }//if

                           else

 

                             //glin -> lin

                             if(fonaux[i+3] == 'N')

                             { fonwrk[j] = fonaux[i+1];

                               fonwrk[j+1] = fonaux[i+2];

                               j += 2;

                               i += 2;

                             }/*if*/

                             else copmud = 1;

                         else copmud = 1;

                       else

 

                         //gn + vogal -> ni + vogal

                         if (fonaux[i+1] == 'N')

                           if((fonaux[i+2]!='a')&&

                              (fonaux[i+2]!='i')&&

                              (fonaux[i+2]!='o'))

                             copmud = 1;

                           else

                           { fonwrk[j] = 'N';

                             fonwrk[j+1] = 'i';

                             j += 2;

                             i++;

                           }//else

                         else

 

                           //   ghi -> gi

                           if (fonaux[i+1] == 'H')

                             if (fonaux[i+2] == 'i')

                             { fonwrk[j] = 'G';

                               fonwrk[j+1] = 'i';

                               j += 2;

                               i +=2;

                             }//if

                             else copmud = 1;

                           else copmud = 1;

                   break;

 

                   case 'H':  //se o caracter for H

 

                   //H eh desconsiderado

                   break;

 

                   case 'i':  //se o caracter for i

 

                     if (fonaux[i+2] == ' ')

 

                       //is ou iz final perde a consoante

                       if (fonaux[i+1] == 's')

                       { fonwrk[j] = 'i';

                         break;

                       }//if

                       else

                         if (fonaux[i+1] == 'Z')

                         { fonwrk[j] = 'i';

                           break;

                         }//if

 

                       //ix

                       if (fonaux[i+1] != 'X')

                         copfon = 1;

                       else

                         if (i != 0)

                           copfon = 1;

                         else

 

                           //ix vogal no inicio torna-se iz

                           if ((fonaux[i+2]=='a')||

                               (fonaux[i+2]=='i')||

                               (fonaux[i+2]=='o'))

                           { fonwrk[j] = 'i';

                             fonwrk[j+1] = 'Z';

                             j += 2;

                             i++;

                             break;

                           }//if

                           else

 

                           //ix consoante no inicio torna-se is

                           if (fonaux[i+2]=='C' || fonaux[i+2]=='s') {

                             fonwrk[j] = 'i';

                             j++;

                             i++;

                             break;

                           }//if

                           else

                             { fonwrk[j] = 'i';

                               fonwrk[j+1] = 's';

                               j += 2;

                               i++;

                               break;

                             }//else

                   break;

 

                   case 'J':  //se o caracter for J

 

                     //J -> Gi

                     fonwrk[j] = 'G';

                     fonwrk[j+1] = 'i';

                     j += 2;

                   break;

 

                   case 'K':  //se o caracter for K

                     //KT -> T

                     if (fonaux[i+1] != 'T')

                       copmud = 1;

                     break;

 

                   case 'L':  //se o caracter for L

 

                     //L + vogal nao eh modificado

                     if ((fonaux[i+1] == 'a')||

                         (fonaux[i+1] == 'i')||

                         (fonaux[i+1] == 'o'))

                       copfon = 1;

                     else

 

                       //L + consoante -> U + consoante

                       if (fonaux[i+1] != 'H')

                         { fonwrk[j] = 'o';

                           j++;

                           break;

                         }//if

 

                         //LH + consoante nao eh modificado

                         else

                           if (fonaux[i+2] != 'a' &&

                               fonaux[i+2] != 'i' &&

                               fonaux[i+2] != 'o')

                             copfon = 1;

                           else

 

                             //LH + vogal -> LI + vogal

                             { fonwrk[j] = 'L';

                               fonwrk[j+1] = 'i';

                               j += 2;

                               i++;

                               break;

                             }

                   break;

 

 

                   case 'M':  //se o caracter for M

 

                     //M + consoante -> N + consoante

                     //M final -> N

                     if ((fonaux[i+1] != 'a' &&

                          fonaux[i+1] != 'i' &&

                          fonaux[i+1] != 'o') ||

                         (fonaux[i+1] == ' '))

                     { fonwrk[j] = 'N';

                       j++;

                     }//if

 

                     //M nao eh alterado

                     else copfon = 1;

                   break;

 

                   case 'N':  //se o caracter for N

 

                     //NGT -> NT

                     if ((fonaux[i+1] == 'G') &&

                         (fonaux[i+2] == 'T'))

                     { fonaux[i+1] = 'N';

                       copfon = 1;

                     }//if

                     else

 

                       //NH + consoante nao eh modificado

                       if (fonaux[i+1] == 'H')

                         if ((fonaux[i+2] != 'a')&&

                             (fonaux[i+2] != 'i')&&

                             (fonaux[i+2] != 'o'))

                            copfon = 1;

 

                         //NH + vogal -> Ni + vogal

                         else

                         { fonwrk[j] = 'N';

                           fonwrk[j+1] = 'i';

                           j += 2;

                           i++;

                         }

                       else copfon = 1;

                   break;

 

                   case 'o':  //se o caracter for o

 

                     //oS final -> o

                     //oZ final -> o

                     if ((fonaux[i+1] == 's') ||

                         (fonaux[i+1] == 'Z'))

                       if (fonaux[i+2] == ' ')

                       { fonwrk[j] = 'o';

                         break;

                       }//if

                       else copfon = 1;

                     else copfon = 1;

                   break;

 

                   case 'P':  //se o caracter for P

 

                     //PH -> F

                     if (fonaux[i+1] == 'H')

                     { fonwrk[j] = 'F';

                       i++;

                       newmud = 1;

                     }//if

                     else

                       copmud = 1;

                   break;

 

                   case 'Q':  //se o caracter for Q

 

                     //Koi -> Ki (QUE, QUI -> KE, KI)

                     if (fonaux[i+1] == 'o')

                       if (fonaux[i+2] == 'i')

                       { fonwrk[j] = 'K';

                         j++;

                         i++;

                         break;

                       }//if

 

                     //QoA -> KoA (QUA -> KUA)

                     fonwrk[j] = 'K';

                     j++;

                   break;

 

                   case 'R':  //se o caracter for R

 

                     //R nao eh modificado

                     copfon = 1;

                   break;

 

                   case 's':  //se o caracter for s

 

                     //s final eh ignorado

                     if (fonaux[i+1] == ' ')

                       break;

 

                     //s inicial + vogal nao eh modificado

                     if ((fonaux[i+1]=='a')||

                         (fonaux[i+1]=='i')||

                         (fonaux[i+1]=='o'))

                       if (i == 0)

                       { copfon = 1;

                         break;

                       }//if

                       else

 

                         //s entre duas vogais -> z

                         if ((fonaux[i-1] != 'a')&&

                             (fonaux[i-1]!='i')&&

                             (fonaux[i-1]!='o'))

                         { copfon = 1;

                           break;

                         }//if

                         else

 

                           //SoL nao eh modificado

                           if ((fonaux[i+1] == 'o') &&

                               (fonaux[i+2] == 'L') &&

                               (fonaux[i+3] == ' '))

                           { copfon = 1;

                             break;

                           }//if

 

                           else

                           { fonwrk[j] = 'Z';

                             j++;

                             break;

                           }//else

 

                     //ss -> s

                     if (fonaux[i+1] == 's')

                       if (fonaux[i+2] != ' ')

                       { copfon = 1;

                         i++;

                         break;

                       }//if

                       else

                       { fonaux[i+1] = ' ';

                         break;

                       }//else

 

                     //s inicial seguido de consoante fica precedido de i

                     //se nao for sci, sh ou sch nao seguido de vogal

                     if (i == 0)

                       if (!((fonaux[i+1] == 'C') &&

                            (fonaux[i+2] == 'i')))

                         if (fonaux[i+1] != 'H')

                           if (!((fonaux[i+1] == 'C') &&

                                (fonaux[i+2] == 'H') &&

                                ((fonaux[i+3] != 'a')&&

                                 (fonaux[i+3]!='i')&&

                                 (fonaux[i+3]!='o'))))

                           { fonwrk[j] = 'i';

                             j++;

                             copfon = 1;

                             break;

                           }//if

 

                     //sH -> X;

                     if (fonaux[i+1] == 'H')

                     { fonwrk[j] = 'X';

                       i++;

                       newmud = 1;

                       break;

                     }//if

                     if (fonaux[i+1] != 'C')

                     { copfon = 1;

                       break;

                     }//if

 

                     //   sCh nao seguido de i torna-se X

                     if (fonaux[i+2] == 'H')

                       { fonwrk[j] = 'X';

                         i += 2;

                         newmud = 1;

                         break;

                       }//if

                     if (fonaux[i+2] != 'i')

                     { copfon = 1;

                       break;

                     }//if

 

                     //sCi final -> Xi

                     if (fonaux[i+3] == ' ')

                     { fonwrk[j] = 'X';

                       fonwrk[j+1] = 'i';

                       i = i + 3;

                       break;

                     }//if

 

                     //sCi vogal -> X

                     if ((fonaux[i+3]=='a')||

                         (fonaux[i+3]=='i')||

                         (fonaux[i+3]=='o') )

                     { fonwrk[j] = 'X';

                       j++;

                       i += 2;

                       break;

                     }//if

 

                     //sCi consoante -> si

                     fonwrk[j] = 's';

                     fonwrk[j+1] = 'i';

                     j += 2;

                     i += 2;

                   break;

 

                   case 'T':  //se o caracter for T

 

                     //TS -> S

                     if (fonaux[i+1] == 's')

                       break;

 

                     //TZ -> Z

                     else

                       if (fonaux[i+1] == 'Z')

                         break;

                       else copmud = 1;

                         break;

 

                   case 'V':  //se o caracter for V

                   case 'W':  //ou se o caracter for W

 

                     //V,W inicial + vogal -> o + vogal (U + vogal)

                     if (fonaux[i+1] == 'a'||

                         fonaux[i+1] == 'i'||

                         fonaux[i+1] == 'o')

                       if (i == 0)

                       { fonwrk[j] = 'o';

                         j++;

                       }//if

 

                       //V,W NAO inicial + vogal -> V + vogal

                       else

                       { fonwrk[j] = 'V';

                         newmud = 1;

                       }//else

 

                     else

                     { fonwrk[j] = 'V';

                       newmud = 1;

                     }//else

                   break;

 

                   case 'X':  //se o caracter for X

 

                     //caracter nao eh modificado

                     copmud = 1;

                   break;

 

                   case 'Y':  //se o caracter for Y

                   //Y jah foi tratado acima

                   break;

 

                   case 'Z':  //se o caracter for Z

 

                     //Z final eh eliminado

                     if (fonaux[i+1] == ' ')

                       break;

 

                     //Z + vogal nao eh modificado

                     else

                       if ((fonaux[i+1] == 'a')||

                           (fonaux[i+1] == 'i')||

                           (fonaux[i+1] == 'o'))

                         copfon = 1;

 

                       //Z + consoante -> S + consoante

                       else

                       { fonwrk[j] = 's';

                         j++;

                       }//else

                       break;

 

                   default: //se o caracter nao for um dos jah relacionados

 

                     //o caracter nao eh modificado

                     fonwrk[j] = fonaux[i];

                     j++;

                   break;

                 }//switch

 

                 //copia caracter corrente

                 if (copfon == 1)

                 { fonwrk[j] = fonaux[i];

                   j++;

                 }//if

 

                 //insercao de i apos consoante muda

                 if (copmud == 1)

                   fonwrk[j] = fonaux[i];

                 if (copmud == 1 || newmud == 1)

                 { j++;

                   k = 0;

                   while (k == 0)

                     if (fonaux[i+1] == ' ')

                     //e final mudo

                     { fonwrk[j] = 'i';

                       k = 1;

                     }//if

                     else

                       if ((fonaux[i+1]=='a')||

                           (fonaux[i+1]=='i')||

                           (fonaux[i+1]=='o'))

                         k = 1;

                       else

                         if (fonwrk[j-1] == 'X')

                         { fonwrk[j] = 'i';

                           j++;

                           k = 1;

                         }//if

                         else

                           if (fonaux[i+1] == 'R')

                             k = 1;

                           else

                             if (fonaux[i+1] == 'L')

                               k = 1;

                             else

                               if (fonaux[i+1] != 'H')

                               { fonwrk[j] = 'i';

                                 j++;

                                 k = 1;

                               }//if

                               else i++;

                     }

 

           }//for

         }//if

       }//else

 

       for (i = 0; i < component.elementAt(desloc).toString().length() + 3; i++)

       //percorre toda a palavra, letra a letra

 

         //i -> I

         if (fonwrk[i] == 'i')

           fonwrk[i] = 'I';

         else

 

           //a -> A

           if (fonwrk[i] == 'a')

           fonwrk[i] = 'A';

           else

 

            //o -> U

            if (fonwrk[i] == 'o')

             fonwrk[i] = 'U';

             else

 

              //s -> S

              if (fonwrk[i] == 's')

               fonwrk[i] = 'S';

               else

 

                //E -> b

                if (fonwrk[i] == 'E')

                 fonwrk[i] = ' ';

                 else

 

                  //Y -> _

                  if (fonwrk[i] == 'Y')

                   fonwrk[i] = '_';

 

       //retorna a palavra, modificada, ao vetor que contem o texto

       component.setElementAt(str.copyValueOf(fonwrk), desloc);

       j = 0; //zera o contador

     }//for

 

     str = vectorToStr(component);

     //remonta as palavras armazenadas no vetor em um unico string

 

     str = removeMultiple(str);

     //remove os caracteres duplicados

 

     return str.toUpperCase().trim();

         }

        

 

 

    public static String removePrep(String str) {

      int i,j;

      Vector palavra = new Vector();

      palavra = strToVector(str);

      String prep[] = {"DEL","DA","DE","DI","DO","DU","DAS","DOS","DEU","DER","E","LA","LE","LES","LOS","VAN","VON","EL"};

 

      for (i = 0; i < palavra.size(); i++) {

        for (j = 0; j < prep.length; j++) {

           if (palavra.elementAt(i).toString().compareTo(prep[j]) == 0) {

             palavra.removeElementAt(i);

             i--;

           }

        }

      }

      return vectorToStr(palavra);

    }

 

 

         public static String removeMultiple (String str) {

  //Retira do texto carateres que estao multiplicados:

  // ss -> s, sss -> s, rr -> r

 

         char[] foncmp = new char[256];

         //matriz de caracteres que armazena o texto sem duplicatas

 

         char[] fonaux = new char[256];

         //matriz de caracteres que armazena o texto original

 

         char[] tip = new char[1]; //armazena o caracter anterior

 

         int i, j;  //contadores

 

         j = 0;

         tip[0] = ' ';

         fonaux = str.toCharArray();

         //a matriz de caracteres recebe o string original

 

         for (i = 0; i < str.length(); i++) {

         //percorre o texto, caracter a caracter

 

           //elimina o caracter se ele for duplicata e

           //nao for numero, espaco ou S

           if ((fonaux[i] != tip[0]) || (fonaux[i] == ' ')

               ||((fonaux[i]>='0') && (fonaux[i]<='9'))

               ||((fonaux[i]=='S')&&(fonaux[i-1]=='S')&&

               ( (i>1) && (fonaux[i-2]!='S')))) {

           foncmp[j] = fonaux[i];

           j++;

           }

 

           tip[0] = fonaux[i];

           //reajusta o caracter de comparacao

         }

 

         //o string recebe o texto sem duplicatas

         str = str.copyValueOf(foncmp);

 

         return str.trim();

       }//removeMultiple

 

 

  public static String removeAccentuation (String str) {

  //Substitui os caracteres acentuados por caracteres nao acentuados

 

         char aux[] = new char[256];

         //matriz de caracteres onde o texto eh manipulado

 

         int i;  //contador

 

         aux = str.toCharArray();

         //matriz recebe o texto

 

         for (i = 0; i < str.length(); i++) {

         //percorre o texto, caracter a caracter

 

           switch (aux[i])

           { case 'É':

               aux[i]='E';  //É -> E

               break;

             case 'Ê':

               aux[i]='E';  //Ê -> E

               break;

             case 'Ë':

               aux[i]='E';  //Ë -> E

               break;

             case 'Á':

               aux[i]='A';  //Á -> A

               break;

             case 'À':

               aux[i]='A';  //À -> A

               break;

             case 'Â':

               aux[i]='A';  //Â -> A

               break;

             case 'Ã':

               aux[i]='A';  //Ã -> A

               break;

             case 'Ä':

               aux[i]='A';  //Ä -> A

               break;

             case 'Ç':

               aux[i]='C';  //Ç -> C

               break;

             case 'Í':

               aux[i]='I';  //Í -> I

               break;

             case 'Ó':

               aux[i]='O';  //Ó -> O

               break;

             case 'Õ':

               aux[i]='O';  //Õ -> O

               break;

             case 'Ô':

               aux[i]='O';  //Ô -> O

               break;

             case 'Ö':

               aux[i]='O';  //Ö -> O

               break;

             case 'Ú':

               aux[i]='U';  //Ú -> U

               break;

             case 'Ü':

               aux[i]='U';  //Ü -> U

               break;

             case 'Ñ':

               aux[i]='N';  //Ñ -> N

               break;

             }

         }

         str = str.copyValueOf(aux).trim();

         //o string recebe o texto sem acentuacao

 

         return str;

       }//removeAccentuation

 

  public static String removeStrange (String str) {

  //Elimina os caracteres que NAO sejam alfanumericos ou espacos

 

         char[] foncmp = new char[256];

         //matriz de caracteres que armazena o texto original

 

         char[] fonaux = new char[256];

         //matriz de caracteres que armazena o texto modificado

 

         int i, j,  //contadores

             first;  //indica se exitem espacos em branco antes do primeiro

                     //caracter: se 1 -> existem, se 0 -> nao existem

 

         j = 0;

         first = 1;

         fonaux = str.toCharArray();

         //matriz de caracteres recebe o texto

 

         for (i = 0; i < 256; i++)

           foncmp[i] = ' ';

           //branqueia a matriz de caracteres

 

         for (i = 0; i < str.length(); i++) {

         //percorre o texto, caracter a caracter

 

           //elimina os caracteres que nao forem alfanumericos ou espacos

           if (((fonaux[i]>='A')&&

               (fonaux[i]<='Z')) ||

              ((fonaux[i]>='a')&&

               (fonaux[i]<='z')) ||

              ((fonaux[i]>='0')&&

                (fonaux[i]<='9')) ||

               (fonaux[i] == '&')  ||

               (fonaux[i] == '_')  ||

               ((fonaux[i] == ' ') && first == 0)) {

             foncmp[j] = fonaux[i];

             j++;

             first = 0;

           }//if

         }//for

         str = str.valueOf(foncmp);

         //string recebe o texto da matriz de caracteres

 

         return str.trim();

       }//removeStrange

 

 

       public static Vector strToVector(String str) {

       //armazena o texto de um string em um vetor onde

       //cada palavra do texto ocupa uma posicao do vetor

 

         str = str.trim();

 

         char[] fonaux = new char[256];

         //matriz de caracteres que armazena o texto completo

 

         char[] foncmp = new char[256];

         //matriz de caracteres que armazena cada palavra

 

         Vector component = new Vector();

         //vetor que armazena o texto

 

         String aux = new String();

 

         int i, j,  //contadores

             pos,   //posicao da matriz

             rep,   //indica se eh espaco em branco repetido

             first; //indica se eh o primeiro caracter

 

         first = 1;

         pos = 0;

         rep = 0;

 

         fonaux = str.toCharArray();

         //matriz de caracteres recebe o texto

 

         for (j = 0; j < 256; j++)

           foncmp[j] = ' ';

           //branqueia matriz de caracteres

 

         for (i = 0; i < str.length(); i++) {

         //percorre o texto, caracter a caracter

 

           //se encontrar um espaco e nao for o primeiro caracter,

           //armazena a palavra no vetor

           if ((fonaux[i] == ' ') && (first != 1)) {

             if (rep == 0) {

               component.addElement(aux.copyValueOf(foncmp).trim());

               pos = 0;

               rep = 1;

               for (j = 0; j < 256; j++)

                 foncmp[j] = ' ';

             }//if

           }//if

 

           //forma a palavra, letra a letra, antes de envia-la a uma

           //posicao do vetor

           else {

             foncmp[pos] = fonaux[i];

             first = 0;

             pos++;

             rep = 0;

           }//else

         }//for

 

         if (foncmp[0] != ' ')

           component.addElement(aux.copyValueOf(foncmp).trim());

 

         return component;

       }//strToVector

 

 

       public static String vectorToStr(Vector vtr) {

       //converte o texto armazenado em um vetor para um unico string

 

         char[] foncmp = new char[256];

         //matriz de caracteres que armazena o texto completo

 

         char[] auxChar = new char[256];

         //matriz de caracteres que armazena cada palavra

 

         String auxStr = new String();

         String str = new String();

         int i, j, desloc;

 

         desloc = 0;  //deslocamento dentro da matriz

 

         for (i = 0; i < 256; i ++)

               foncmp[i] = ' ';

               //branqueia a matriz de caracteres

 

         for (j = 0; j < vtr.size(); j++) {

         //percorre o vetor, palavra a palavra

 

           auxStr = (vtr.elementAt(j)).toString().trim();

           //string recebe a palavra armazenada pelo vetor

 

           auxChar = auxStr.toCharArray();

           //matriz de caracteres recebe a palavra armazenada no vetor

 

           for (i = 0; i < auxStr.length(); i++)

           //percorre a matriz, caracter a caracter

 

             foncmp[desloc + i] = auxChar[i];

           desloc = desloc + auxStr.length() + 1;

         }//for

 

         str = str.valueOf(foncmp);

         //string recebe o texto completo

 

         return str.trim();

 

       }//vectorToStr

}