# XBUP - Implementace proudového zpracování

### Úvod

Tento dokument je součástí dokumentace projektu eXtensible Binary Universal Protocol. Obsahuje popis implementace proudového zpracování.

O úroveň výše

### Obsah

1. Implementace proudového zpracování
1.1. Přehled rozhraní
2. Rozhraní proudových tříd
2.1. Rozhraní pro události
2.2. Rozhraní datových proudů
3. Převodní třídy
3.1. Změna řízení toku
3.2. Parsování
3.3. Zpracování vzorem
4. Příklady použití
5. Reference

### 1. Implementace proudového zpracování

Implementace proudového zpracování se snaží pro vybrané varianty datových proudů poskytnout potřebnou funkcionalitu ve formě tříd a rozhraní. Implementace by měla být zahrnuta do balíku xblib a povinně dostupná ve všech implementacích. Tam kde je to možné, jsou rozšiřovány existující implementace proudového zpracování jako základ pro konstrukci nadtříd a případně i názvy metod a typy parametrů.

Jako inspirace poslouží obdobný projekt pro XML nazývaný XStream, který však jde ještě dále a využívá pokročilých vlastností jazyka Java.

### 1.1. Přehled rozhraní

Implementace řeší jak vlastní předávání dat, tak i řízení toku (komunikaci) a transformace jednotlivých typů dat.

- Rozhraní proudových tříd - rozhraní tohoto typu poskytují funkcionalitu pro vlastní přenos dat mezi proudovými třídami a klientem
- Rozhraní řízení datového toku - tato rozhraní umožňují změnit chování datového toku, jako například změna pozice v proudu, či předčasné ukončení proudu.

Základní rozhraní jsou následující:

Typ rozhraní | Typ řízení | Odesílání dat | Příjem dat | Odesílání s přerušením | Příjem s přerušením | Podpora serializace | Zpracování proudu
--- | --- | --- | --- | --- | --- | --- | ---
Široké rozhraní | Řízeno odesílatelem | XBProvider | XBListener | - | - | XBSerializable | XBFilter
Řízeno příjemcem | XBProducer | XBConsumer | - | - | - | -
Předávání tokenu | Řízeno odesílatelem | XBEventProvider | XBEventListener | XBEventProducer | XBEventConsumer | XBEventSerializable | XBEventFilter
Řízeno příjemcem | XBPullProvider | XBPullListener | XBPullProducer | XBPullConsumer | XBPullSerializable | XBPullFilter
Proudové rozhraní | Řízeno odesílatelem | XBOutputStream | - | - | - | XBStreamable | XBStreamFilter
Řízeno příjemcem | - | XBInputStream | - | - | XBStreamable | XBStreamFilter

### 2. Rozhraní proudových tříd

Rozhraní proudových tříd se liší podle šířky rozhraní, způsobu řízení toku a podpory paralelního zpracování.

### 2.1. Rozhraní pro události

Jednou z možností je předávat data skupinou metod, kdy každému typu dat odpovídá právě jedna metoda. Jednotlivé metody odpovídají typům položek tak, jak jsou používány v parserech. Případně je možné data přenášet pomocí položek, které v sobě nesou informaci o typu přenášených položek. Položky jsou pak předávány pomocí jediného parametru jediné metody.

- XBEventListener - Třída, která implementuje toto rozhraní deklaruje, že je shopna přijímat události protokolu XBUP na definovaném rozhraní. Její synchronní varianta pak zaručuje schopnost přijímat události paralelně - obvykle při zpracování události vstoupí do kritické sekce. Rozšíření XBEventConsumer je rozhraní rozšířené o metodu pro reinicializaci příjmu událostí.
- XBEventProvider - Třída, která implementuje toto rozhraní deklaruje, že je schopna generovat události protokolu XBUP. Opět je k dispozici rozšíření XBEventProducer, které disponuje metodou pro opakované poslání všech událostí.
- XBEventFilter - Implementací vstupního i výstupního rozhraní lze danou třídu považovat za filter událostí. Speciální variantou tohoto rozhraní je pak rozšíření XBEvent na odlišný vstupní a výstupní proud
- XBEventSerializable - Toto rozhraní poskytuje dvě metody, které umožňují provést napojení na jak příjem, tak vyslání událostí a jejich zpracování na vnitřní stav třídy.

### 2.2. Rozhraní datových proudů

Rozhraní pro datové proudy (streams) poskytuje možnost opačného řízení proudu dat a poskytuje oba dva druhy používá především úzké rozhraní. Promě toho může rozhraní podporovat další metody pro řízení toku dat, jako například pohyb v toku na začátek, o zvolený rozsah vpřed či vzad.

- XBInputStream - Vstupní proud s řízením toku příjemcem. Třída implementující toho rozhraní deklaruje, že je schopna generovat události a poskytuje funkci pro postupné získání událostí (pulling). K vstupnímu proudu je k dispozici rozhraní XBInputStreamFilter, které umožňuje provádět filtrování proudu.
- XBOutputStream - Výstupní proud s řízení toku odesílatelem. Třída implementující toto rozhraní je schopna pomocí funkce přijímat jednotlivé události. Synchronní varianta dokáže přijímat události od více souběžných proudů najednou. K výstupnímu proudu je k dispozici rozhraní XBOutputStreamFilter, které umožňuje provádět filtrování proudu.
- XBStreamable - Rozhraní indikuje metody umožňující serializaci objektu do vstupního i výstupního proudu.

### 3. Převodní třídy

K dispozici jsou dále standardní třídy, které umožňují provádět převody mezi různými typy proudu, případně provádět některé druhy transformací nad proudy.

### 3.1. Změna řízení toku

Mezi oběma formami řízení komunikace je možné převádět.

- proud -> události: cyklickým voláním
- události -> proud:

### 3.2. Parsování

Třídy pro parsování kombinují techniky parsování s převodem na některý z typů proudu.

### 3.3. Zpracování vzorem

Zpracování vzorem definuje příjem proudu definicí příchozích položek tak, jak by měli přicházet. Zároveň jsou těmito funkcemi vráceny přijaté hodnoty.

- XBStreamChecker - Pro datové proudy poskytuje široké rozhraní pro zpracování vzorem.

### 4. Příklady použití

Následuje několik příkladů možných využití implementovaných tříd a rozhraní.

### 4.1. Serializace objektů

Proud je možné s výhodou využít například pro serializaci objektů. Pro jednotlivé úrovně protokolu je definováno rozhraní, které zpřístupňuje funkce konverze na datový proud a zpět, které pak umožňuje transformaci vybraných dat protokolu na posloupnost položek tak jak byly definovány v událostech parsování.

Tyto rozhraní jsou následující:

- XBStreamable - deklaruje transformaci do základního kódování bez definice typů bloků. Mělo by vytvořit jediný blok obsahující všechny data o objektu. Má následující přístupové metody:
  void WriteToXB(XBOutputStream stream) - metoda pro zápis do proudu
  void ReadFromXB(XBInputStream stream) - metoda pro čtení z proudu
- XBLxStreamable - deklaruje transformaci do vyšších úrovní protokolu XBUP, tedy vytváří typovaný blok a napojení na typ dokumentu. Hodnota x odpovídá číslu úrovně. Má tři přístupové metody:
  XBTypeBlock getLxBlockType() - Vrací typ bloku
  void WriteToLxXB(XBLxOutputStream stream) - metoda pro zápis do proudu
  void ReadFromLxXB(XBLxInputStream stream) - metoda pro čtení z proudu
- XBCLxStreamable - deklaruje transformaci do vyšších úrovní protokolu XBUP s využitím katalogu:
  XBTypeBlock getCLxBlockType(XBLxCatalogHandler catalog) - vrací typ kořenového bloku z katalogu
  void WriteToCLxXB(XBLxOutputStream stream, XBLxCatalogHandler catalog) - metoda pro zápis do proudu
  void ReadFromCLxXB(XBLxInputStream stream, XBLxCatalogHandler catalog) - metoda pro čtení z proudu
- XBMultiStreamable - definuje více možných způsobů převodu objektu na data v základním tvaru s následujícími přístupovými metodami:
  int getXBMCount() - metoda vrací počet možných způsobů zápisu proudu
  void WriteToXBM(XBOutputStream stream, int type) - metoda pro zápis do proudu
  void ReadFromXBM(XBInputStream stream, int type) - metoda pro čtení z proudu
- XBLxMultiStreamable - obdoba předchozího rozhraní pro vyšší úrovně, metody jsou obdobné:
  int getLxXBMCount() - metoda vrací počet možných způsobů zápisu proudu
  XBTypeBlock getLxBlockType(int type) - Vrací typ bloku
  void WriteToLxXBM(XBLxOutputStream stream, int type) - metoda pro zápis do proudu
  void ReadFromLxXBM(XBLxInputStream stream, int type) - metoda pro čtení z proudu

### 1.2.1. Příklad využití proudu

Následující příklad ukazuje možné využití proudu v programovacím jazyce Java pro serializaci textového řetězce. Jde o implementaci v pracovní verzi WR-16:

    public class XBString implements XBCL1Streamable {

        private String value;

        /** Creates a new instance of XBString */
        public XBString() {
            this.value = "";
        }

        public XBString(String value) {
            this.value = value;
        }

        public XBL1Declaration getXBL1Declaration() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        /** Serialize object to XBUP Level 1 Stream */
        public void writeXBL1Stream(XBL1OutputStream stream) throws IOException {
            try {
                XBL1Listener listener = XBL1DefaultEventListener.toXBListener(stream);
                listener.beginXBL1(false);
                listener.typeXBL1(new XBCPContextBlock(xbBlockPath));
                listener.attribXBL1(new UBNat32(1)); // Data block pointer
                listener.beginXBL1(false);
                listener.dataXBL1(getValue().getBytes());
                listener.endXBL1();
                listener.endXBL1();
            } catch (XBParseException ex) {
                Logger.getLogger(XBString.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        /** Serialize object from XBUP Level 1 Stream */
        public void readXBL1Stream(XBL1InputStream stream) throws XBProcessingException {
            try {
                XBL1StreamChecker checker = new XBL1StreamChecker(stream);
                checker.beginXBL1();
                checker.typeXBL1(new XBCPContextBlock(xbBlockPath));
                checker.attribXBL1(new UBNat32(1)); // Data block pointer
                checker.beginXBL1();
                setValue(new String(checker.dataXBL1()));
                checker.endXBL1();
                checker.endXBL1();
            } catch (XBParseException ex) {
                Logger.getLogger(XBString.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(XBString.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

### 5. Reference

Seznam zdrojů, literatury a relevantních odkazů.

XStream - obdobná implementace pro XML [http://xstream.codehaus.org/]

Homepage: http://xbup.sf.net
License: GNU Free Documentation License (FDL)
Latest update: 2009-06-28