Usando banco de dados XML em Java com o eXist
Neste meu primeiro artigo para o portal vou tratar de um tópico bastante falado na área da computação: armazenamento de documentos XML.
É bastante comum encontrarmos sistemas que utilizam XML para armazenar configurações, logs, ou ainda para representar mensagens numa comunicação remota (como é o caso do protocolo SOAP - Simple Object Access Protocol - usado pelos tão famosos WebServices).
A ferramenta eXist trata exatamente de armazenar e consultar informações em XML (apesar de ela suportar arquivos binários, não iremos tratar disto neste artigo) de forma eficiente e simples. Vamos mostrar como instalar o software e executar as operações básicas de inserção, remoção e recuperação de documentos utilizando uma API em Java.
Esse artigo foi escrito baseado na versão 1.0 disponível no link http://exist-db.org/index.html#download.
O eXist é distribuído de duas formas: um JAR executável ou um WAR. Se optar pelo WAR você precisará de um container Web para fazer a instalação. No entanto, o JAR executável já vem com o Jetty (http://jetty.mortbay.org) como container e você não precisará se preocupar com instalações adicionais.
Como o deploy no container depende do servidor que está sendo usado (Tomcat, Jetty ou outro), iremos mostrar apenas como instalar o JAR executável:
- Abra um console (DOS ou Terminal se for Windows ou Linux respectivamente);
- Entre no diretório onde você salvou o JAR do eXist;
- Digite java -jar eXist-[versão].jar;
- Prossiga a instalação com o Wizard que irá se abrir.
Pronto, já temos o banco de dados instalado!!
Para iniciar e parar o banco, utilize os scripts startup e shutdown, respectivamente, que estão no diretório bin da instalação do eXist. Se você observar, existem dois arquivos para cada um desses scripts no diretório bin: o sh é para o Linux e o bat é para rodar no Windows.
Antes de mexermos com código em Java, é importante saber o conceito de coleções e recursos adotado pelo eXist.
O termo Collection é utilizado para se referenciar a um diretório de armazenamento de documentos XML. Essas coleções são organizadas de forma hierárquica e um exemplo pode ser visualizado na figura abaixo (Figura 01).
Figura 01. Estrutura hierárquica de um collection.
O exemplo mostrado na figura define quatro coleções, sendo estas: /raiz, /raiz/teste, /raiz/filho e /raiz/filho/arq (a barra “/” é usada como delimitadora de nível). Note também que duas coleções (/raiz/teste e /raiz/filho) possuem XMLResources, que são os próprios documentos XML que são armazenados nas coleções.
Tendo estes conceitos em mente e assumindo que o banco de dados está executando, mostraremos como fazer as operações básicas utilizando a API em Java que é distribuída junto com o eXist.
Vamos criar uma classe que insere um documento numa coleção do banco. (Por motivos de simplificação, vou me referir a EXIST_DIR para designar o diretório de instalação do eXist.)
import java.io.File;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.modules.CollectionManagementService;
import org.xmldb.api.modules.XMLResource;
public class InsercaoExemplo {
public final static String URI =
"xmldb:exist://localhost:8080/exist/xmlrpc/db";
public static void main(String args[]) throws Exception {
if(args.length < 2) {
System.err.println("* Uso: InsercaoExemplo <caminho-colecao>
<documento>");
System.exit(1);
}
String colecao = args[0], documento = args[1];
if (! colecao.startsWith("/") ) {
System.err.println("* Erro: O nome da colecao deve iniciar com uma
barra '/'");
System.exit(2);
}
// inicializando driver
String driver = "org.exist.xmldb.DatabaseImpl";
Class cl = Class.forName(driver);
Database database = (Database)cl.newInstance();
DatabaseManager.registerDatabase(database);
// tenta pegar a colecao
Collection col = DatabaseManager.getCollection(URI + colecao);
if(col == null) {
// colecao nao existe: pega a colecao raiz e cria a nova
Collection raiz = DatabaseManager.getCollection(URI);
CollectionManagementService mgtService =
(CollectionManagementService) raiz.getService("CollectionManagementService",
"1.0");
col = mgtService.createCollection(colecao);
}
File f = new File(documento);
if(!f.canRead()) {
System.err.println("* Erro: Nao foi possivel ler o arquivo " +
documento);
System.exit(3);
}
// cria o novo XMLResource
XMLResource document = (XMLResource) col.createResource(f.getName(),
"XMLResource");
document.setContent(f);
System.out.print("> Armazenando documento '" + document.getId() +
"' ...");
col.storeResource(document);
System.out.println(" ok!");
}
}
Observe que este comando só funciona no Windows. Para rodá-lo no Linux troque os “;” por “:” e as “\” (contra-barra) por “/” (barra).
Tendo entendido o código acima, torna-se bastante simples as demais operações básicas no eXist. Por exemplo, para recuperar um documento armazenado é possível utilizar a chamada “getResource()” da coleção, e para remover basta trocar a chamada ao “storeResource()” pela chamada ao “removeResource()” no exemplo.
A documentação da API Java está disponível para consulta no endereço http://exist.sourceforge.net/api/index.html.
Gostaria de finalizar esse artigo citando algumas funcionalidades do eXist que ficaram de fora do escopo deste artigo e que podem futuramente ser abordadas.
- Consulta a dados utilizando XQuery;
- Diferentes modos de instalação do eXist (embutido numa aplicação desktop ou como parte de uma aplicação Web);
- Configurações avançadas de desempenho.
Agradeço a todos pelo acompanhamento do artigo e espero que tenha sido útil como um primeiro passo no uso da ferramenta. Qualquer dúvida pode ser discutida através de comentários ao artigo ou através do meu e-mail (flavio@cgjug.com.br).
Muito obrigado pessoal!!