Tutorial do HierarchicalMap - Nível Intermediário

HierarchicalMap é uma interface. Assim, qualquer um pode implementá-la. Este tutorial é baseado em BasicHierarchicalmap, uma implementação referência em Java da interfae HierarchicalMap.

Este tutorial abrange os seguintes assuntos:

    Nível Básico
  1. O Primeiro Contato
  2. Criação de Estruturas
  3. Recuperação dos Dados
  4. Interação com Coleções
  5. Reestruturação do Mapa

  6. Nível Intermediário
  7. Trabalhando com Stream
  8. Trabalhando com XML
  9. Trabalhando com XML Grande
  10. Acessando Banco de Dados
  11. Acessando Preferências

  12. Nível Avançado
  13. Preenchimento de Template (inglês)
  14. Interoperabilidade com .NET (inglês)
  15. Runtime schema validation (inglês)

(O recurso de Javascript precisa estar habilitado, no seu navegador, para permitir a visualização dos códigos utilizados nos exemplos deste tutorial)

Nível Intermediário

6. Trabalhando com Stream

HierarchicalMap pode ser convertida em fluxo de dados de dois tipos: formato Binário ou formato XML. O pacote org.dhmp.io cotém classes que auxilia a manipulação de fluxo de dados:

  • Formato Binário: MapInputStream e MapOutputStream
  • Formato XML: XMLMapInputStream e XMLMapOutputStream
  • Classes auxiliares: MapReader e MapWriter
  • Escrever e ler uma HierarchicalMap é simples e direto:

    Para a serialização, é preferível utilizar os mecanismos nativos do Java em vez de utilizar as classes acima. Estas classes, utilizam internamente um cache para evitar loop infinito quando o mapa conter referências recursivas. Portanto, não compartilhe esta classe para várias gravações/leituras de HierarchicalMap, como nos casos de servidores de aplicação. Nestes casos, é melhor recriar esta classe a cada nova requisição evitando o crescimento demasiado do cache.

    Existem mais três métodos para leitura/escrita de HierarchicalMap: readMap(início), readMap(início, término) e readMapUntil(término).

    O MapInputStream varre a estrutura durante a operação de leitura. Para entender melhor como funciona, imagine um cursor fictício que se encontra entre nós. Quando a chave "início" é especificado, a operação de leitura efetivamente começa quando a posição do cursor imaginário cruzar a chave "início". De modo semelhante, a chave "término" indica para MapInputStream terminar de ler imediatamente antes da ocorrência da chave.

    A próxima figura mostra o que acontece quando a operação readMap("A","B/F") é executado sobre a seguinte estrutura:

    Note que a leitura inicia logo após a posição do cursor ultrapassar o nó "A". E termina pouco antes da posição do cursor passar pelo nó "F". Esteja atento de que a chave "término" é relativo em relação à chave "ínicio" e somente os nós são considerados como chave.

    As linhas acimas produzirão a seguinte saída:

    readMap("A","B/F"):
    <B><C><D>valor D</D><E>valor E</E></C></B>
    readMap():
    <F><G>valor G</G><H>valor H</H></F>
    readMap():
    <I><J><K>valor K</K></J></I>

    Como mencionado anteriormente, somente os nós são considerados. Assim, a chamada readMap("A","B/C/E") no lugar do readMap("A","B/F"), resultará na leitura do mapa inteiro, porque não encontrará a chave de "término" ("B/C/E" é uma folha) na estrutura.

    7. Trabalhando com XML

    Trabalhar com XML pode ser feita de maneira bem semelhante. Esta implementação da HierarchicalMap utiliza Apache's Xerces project para manipulação de XML.

    XML é uma estrutura de dados poderosa com vários conceitos como documentos, elementos, atributos, namespaces e assim por diante. A HierarchicalMap possui somente nós (uma outra HierarchicalMap) e folhas (qualquer outro objeto). Portanto, algumas simplificações precisam ser feitas para mapear um XML utilizando a HierarchicalMap.

    O arquivo XML abaixo será utilizado nos próximos exemplos.

    Crie um arquivo de texo, "exemplo.xml", contendo o XML acima e coloque no diretório "/temp".

    A leitura de um arquivo de XML para HierarchicalMap é similar à leitura de fluxos binários.

    O resultado do código acima será uma longa linha de caracteres como a seguinte:

    <Root_Element><Root_attribute>roots attribute ...

    Copie o resultado acima para um arquivo texto e salve com o nome "resultado.txt". Em seguida, abra com um editor de texto compatível com XML (ex: Internet Explorer). O primeiro trecho do arquivo será como seguinte:

    - <Root_Element>
        <Root_attribute>roots attribute</Root_attribute> 
        <_Element_Value>roots text</_Element_Value> 
        <Element /> 
        <ElementWithValue>elements value</ElementWithValue> 
      - <ElementWithChild>
        - <Element>
            <Attrib1>a1</Attrib1> 
            <Attrib2>a2</Attrib2> 
          </Element>
        - <Element>
            <Attrib3>a3</Attrib3> 
            <Attrib4>a4</Attrib4> 
            <_Element_Value>e0</_Element_Value> 
          </Element>
          ...

    Perceba que o arquivo é ligeiramente diferente do arquivo XML original:

    Normalmente, este tipo de simplificação não afeta a interpretação dos dados contidos num documento XML. Porém, algumas vezes será necessário preservar a estrutura original do XML. A única forma para isto na HierarchicalMap é através de encapsulamento de cada tipo de folha com classes distintos. Existem algumas classes de encapsulamento para esta finalidade: org.dhmp.util.xml.Attribute para atributos e org.dhmp.util.xml.ElementValue para valores de elementos.

    XMLMapInputStream possui uma opção para encapsular automaticamente as folhas utilizando estas classes.

    Atente na inicialização da linha "xin.init("<Param pure='true'/>")". Este parâmetro, instrui a classe XMLMapInputStream para preservara estrutura do XML original, encapulando as folhas quando necessário. A classe XMLMapOutputStream reconhece estas classes de encapsulamento e converte para a sintaxe XML correspondente. Abra o arquivo "sample.xml" e o "result2.xml" utilizando um navegador para confirmar que não há diferença entre os mesmos.

    Segue abaixo um outro caso de uso da classe XMLMapInputStream:

    O código acima é utilizado na inicialização da XMLMapInputStream para alterar os parâmetros de funcionamento da mesma.


    Continua para Nível Intermediário - Trabalhando com XML Grande