quinta-feira, 11 de setembro de 2008

Sistema de Busca Off-line

Meu amigo me pediu uma ajuda para fazer um sistema de busca off-line. Entende-se off-line como um sistema de busca que pode ser executado de dentro de um cd/pen-drive sem que fosse necessário ter um servidor e/ou banco de dados para isso. O sistema deveria ser multiplataforma também.

Para ilustrar, vamos imaginar um sistema que busque dados de artigos acadêmicos em uma mídia qualquer e os dados são obtidos a partir de um arquivo de dados.

Para resolver esse problema, utilizei um sitema feito em javascript que roda a partir do navegador web. A estrutura dos arquivos deve ser conforme a figura ao lado. Uma pasta raiz chamei de busca_offline com um diretório de scripts, um arquivo de dados (base.dat) e um index.html para apresentação do resultado.

O sistema se baseia em uma chamada via HttpRequest, carregando o arquivo com os dados base.dat; a partir de então a busca é feita sobre o arquivo carregado utilizando-se expressões regulares.

O arquivo de dados base.dat é do tipo texto (codificado em UTF-8), com os campos de interesse separados pelo caracter #:

base.dat

João Paulo Eiti Kimura#Programas para busca OFF-LINE
Alcides Ribeiro Jr.#Testes e experimentações com algebra
Zulaide Ribeiro da Silva#Ultra-som de potência para Terapia
José da Silvã# AJAX e suas maravilhas com Javascript
Márcia Kímura# Técnica Marcação de orgãos em Radioterapia
Paulo Antônio Machado# Java EE Segunda Edição
Roberto Pereira de Melo# Programação Orientada a Eventos
Flavia Renata de Souza# Medidor de Fluxo sanguíneo
Roberto Murari# Recursos Humanos e marketing


O Javascript responsável por carregar o arquivo de dados e efetuar as buscas é mostrado a seguir.

engine.js

1 var objArray;
2 var respText;
3
4 /* carrega o arquivo de dados*/
5 function loadResources()
6
{
7 AJAXRequest();
8 }
9
10 /* faz o parser do arquivo lido separando por linhas */
11 function parseResponse(responseText)
12
{
13 objArray = responseText.split("\n");
14 data = "";
15
16 for(i = 0; i < objArray.length; i++){
17 data+= i + " = " + objArray[i].split("#") + "\n";
18 }
19
20 document.getElementById("sresult").value = data;
21
22 }
23
24 /* ajusta os parâmetros adicionando acentuação nas buscas */
25 function adjustParam(param)
26
{
27 param = param.replace(/[aãâáà]/gi, "[aãâáà]");
28 param = param.replace(/[eêéè]/gi, "[eêéè]");
29 param = param.replace(/[iíì]/gi, "[iíì]");
30 param = param.replace(/[oôóò]/gi, "[oôóò]");
31 param = param.replace(/[uúùü]/gi, "[uúùü]");
32
33 param = param.replace(/[cç]/gi, "[cç]");
34
35 return param;
36 }
37
38 /* efetua uma busca em todos os elementos do vetor */
39 function doSearch(param)
40
{
41 param = adjustParam(param);
42 var found = false;
43 var links = "";
44
45 //percorre todos os registros
46 for(i = 0; i < objArray.length; i++){
47
48 var pattern = new RegExp(param,"gi");
49
50 var str = objArray[i];
51 found = pattern.exec(str);
52
53 if (found)
54 {
55 links += "<div > <a href='#'>" + str.split("#") + "</a></div>";
56 }
57
58 }
59
60 document.getElementById("resultArea").innerHTML = links;
61 }
62
63 /* Esse método instancia o objeto XMLHttpRequest*/
64 function GET_XMLHTTPRequest()
65
{
66 var request;
67
68 // Lets try using ActiveX to instantiate the XMLHttpRequest object
69 try{
70 request = new ActiveXObject("Microsoft.XMLHTTP");
71 }catch(ex1){
72 try{
73 request = new ActiveXObject("Msxml2.XMLHTTP");
74 }catch(ex2){
75 request = null;
76 }
77 }
78
79 // check if it supports httprequest
80 if(!request && typeof XMLHttpRequest != "undefined"){
81 //The browser does, so lets instantiate the object
82 request = new XMLHttpRequest();
83 }
84
85 return request;
86 }
87
88
89 function AJAXRequest()
90
{
91 //instancia objeto
92 var myXMLHttpRequest = GET_XMLHTTPRequest();
93
94 //Make sure the XMLHttpRequest object was instantiated
95 if (myXMLHttpRequest)
96 {
97 //carrega o arquivo de dados
98 myXMLHttpRequest.open("GET", "base.dat", true);
99
100 //função que trata a requisição quando o request termina
101 myXMLHttpRequest.onreadystatechange = function (aEvt) {
102
103 if(myXMLHttpRequest.readyState == 4){
104 parseResponse(myXMLHttpRequest.responseText);
105 }
106 };
107 myXMLHttpRequest.send(null);
108 }
109 else
110 {
111 //Oh no, the XMLHttpRequest object couldn't be instantiated.
112 alert("A problem occurred instantiating the XMLHttpRequest object.");
113 }
114 }



O método doSearch(linha 39) faz a busca de um determinado texto no campos do arquivo de dados carregado. O método adjustParam(linha 25), utiliza expressões regulares para ajustar os parâmetros da busca de forma que sejam ignorados os caracteres acentuados.

O código do arquivo index.html de apresentação dos dados é mostrado abaixo.

index.html


1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4 <title>Busca offline</title>
5 <script src="script/engine.js" type="text/javascript"></script>
6 </head>
7 <body onload="javascript:loadResources();">
8
9 <h1>Busca Off-line</h1>
10 <br />
11
12 <input type="text" id="fsearch"> &nbsp;
13 <button name="btnsearch" value="Search"
14 onclick=
"javascript:doSearch(document.getElementById('fsearch').value);">

15 Search </button>
16 <br/><br/>
17
18 <div>
19 <textarea rows="10" cols="70" id="sresult"></textarea>
20 </div>
21 <br/><br/>
22
23 <h1> Resultado </h1>
24 <div id="resultArea">
25 </div>
26 </body>
27 </html>



Quando a página html é carregada, o arquivo de dados também é carregado na memória (linha 7). Nessa página, temos um campo para busca, um botão search (linhas 13,14 e 15) que irá chamar a engine de busca.

Por conveniência criei um textarea para exibir os dados que foram carregados do arquivo (linha 19). E, por fim, uma div que irá exibir os resultados da nossa busca (linha 24).
A figura abaixo mostra como fica a apresentação da engine de busca off-line:


No caso da imagem de exemplo, foi efetuada uma busca pela palavra terapia. Note que o os resultados que retornara foram referentes as palavras: Terapia e Radioterapia.

Para alterar os links do resultado, basta alterar a linha 55 do arquivo engine.js. Essa micro-engine de busca pode ser utilizada totalmente off-line, colocada dentro de um pen-drive, CD ou DVD. Tem a vangatem de ser multiplataforma e usa ferramentas livres de licença.

Download do código fonte: busca_offline.zip

Nenhum comentário: