Porovnávané verzie

Kľúč

  • Tento riadok sa pridal
  • Riadok je odstránený.
  • Formátovanie sa zmenilo.
Komentár: Vrátené z verzie 10

Obsah

Vo verzii 10.1.39-build4 pribudla do knižnice JAPI možnosť aplikačne definovať objekty, ktoré výrazným spôsobom prispievajú k typovo bezpečnej komunikácii pri RPC volaniach. Balíček sk.ipesoft.d2000.d2japi.annotations obsahuje triedy a anotácie pre definovanie mapovania.

...

4.3.2.4. Mapovanie parametra so štruktúrovaným typom

Blok kódu
languagejava
themeEclipse
@RPC(name = "Redim",

...


	parameters =

...


	{
		@Parameter(name = "n", type = ParameterType.integer, inOut = false),

...


		@Parameter(name = "r", type = ParameterType.record, recordType = Person.class)

...


	})

...


@ReturnValue(name = "r")

...


public List<Person> redim(

...


	@ParameterValue(name = "n") Integer length,

...


	@ParameterValue(name = "r") List<Person> data);

Metóda redim mapuje RPC, ktorej druhým formálnym parametrom je štruktúrovaná hodnota. Pre správne mapovanie je typ parametra v anotácii nastavený na @Parameter.type = ParameterType.record a nepovinný parameter anotácie @Parameter.recordType = Person.class. Použitá definícia štruktúry SD.Person a jej mapovanie triedou Person pochádza z kapitoly 5.2.1.

Pri použití metódy redim bude pre účely návratovej hodnoty vytvorená nová inštancia typu List<Person> a jej prvky budú nové inštancie typu Person napriek tomu, že majú rovnaký obsah ako inštancie, ktoré boli použité ako parametre.

4.3.2.5. Mapovanie asynchrónneho volania a časovej značky hodnoty

...

Blok kódu
languagejava
themeEclipse
@RPC(name = "SetValue",

...


	asynchronous = true,

...


	parameters =

...


	{
		@Parameter(name = "v", type = ParameterType.time, inOut = false)

...


	})

...


public void setValue(

...


	@ParameterValue(name = "v") Date value,

...


	@ParameterAttribute(name = "v", attributeType = UnivalAttributeType.valueTime)

...


	Long valueTime);

Metóda setValue sa od predošlých príkladov odlišuje tým, že mapuje asynchrónne volanie (RPC.asynchronous = true). To znamená, že z pohľadu používateľa skončí jej volanie okamžite (po odoslaní správy) a nečaká sa na doručenie odpovede o výsledku. Preto tiež asynchrónna metóda nemôže pristupovať ku výstupnej časti parametrov volania a teda nemôže použiť anotáciu @ReturnValue alebo @ReturnAttribute a takisto nemôže nastaviť parametre anotácií ParameterValue.direction a ParameterAttribute ParameterAttribute.direction na hodnoty inout alebo out.

Nová anotácia @ParameterAttribute mapuje vybraný unival atribút – v tomto prípade časovú značku hodnoty (attributeType = UnivalAttributeType.valueTime) . Pozor, nie je dovolené zavolať metódu s null hodnotou null hodnotou tohto parametra – mapovanie null na atribút univalu nie je možné.

V príklade je zámerne použitý iný typ parametra value (java.util.Date) a parametra valueTime (java.lang.Long). Obidva typy je možné rovnako dobre použiť na mapovanie hodnoty vyjadrujúcej „D2000 absolútny čas", ich výber je na tvorcovi mapovania.

4.3.2.6. Mapovanie procedúry s dvomi výstupnými štruktúrovanými parametrami

...

Blok kódu
languagejava
themeEclipse
@RPC(name = "GetDataAndMetadata",

...


	asynchronous = false,

...


	parameters =

...

 
		{
			@Parameter(
				name = "data",

...


				inOut = true,

...


				type = ParameterType.record,

...


				recordType = Person.class),

...


			@Parameter(

...


				name = "meta",

...


				inOut = true,

...


				type = ParameterType.record,

...


				recordType = Metadata.class)})

...


public void getDataAndMetadata(

...


	@ParameterValue(name = "data") InOut<List<Person>> data,

...


	@ParameterValue(name = "meta") InOut<List<Metadata>> meta);

Metóda getDataAndMetadata mapuje procedúru s dvomi vstupno-výstupnými parametrami (2 parametre s inOut = true). V porovnaní s predošlými metódami stojí za povšimnutie:

  • Typ parametra data je InOut<List<Person>>  Generickým   Generickým parametrom kontajnera InOut je generický List, ktorého parametrom je trieda Person, ktorej mapovanie na SD.Person je popísané v kapitole 5 4.2.1.
  • Trieda Metadata mapuje definíciu štruktúry SD.Metadata. Jej definíciu v príkladoch neuvádzame.
  • Inštancia objektu typu List, ako aj inštancie predstavujúce jeho prvky, ktoré sa nachádzajú v kontajneri typu InOut po skončení synchrónneho volania sú vždy iné, ako inštancie, ktoré sa v kontajneri nachádzali na začiatku volania. Toto správanie je vlastnosť knižnice JAPI.

Kotva
_Ref441670798
_Ref441670798
Kotva
_Toc490141259
_Toc490141259
4.3.3. Volanie z ESL do JAPI – príklad s komentármi

V nasledujúcej ukážke bude uvedený zdrojový kód triedy ExampleHandler. Je to aplikačne definovaná trieda, ktorej metódy môžu byť volané ako RPC z prostredia ESL Môžu byť volané aj z prostredia internej Javy a tiež z prostredia JAPI..
import ako RPC z prostredia ESL .

Blok kódu
languagejava
themeEclipse
import sk.ipesoft.d2000.d2japi.annotations.ParameterType;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.Parameter;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.ParameterValue;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.RPC;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.ReturnValue;

...



public class ExampleHandler

...


{

...


	@RPC(name = "Parse",

...


		parameters =

...


		{
			@Parameter(name = "text", type = ParameterType.text, inOut = false),

...


			@Parameter(name = "result", type = ParameterType.integer)

...


		})

...


	@ReturnValue(name = "result")

...


	public Integer parseInt(

...


		@ParameterValue(name = "text") String text)

...


	{
		try
		{
			return Integer.parseInt(text);

...


		}
		catch (NumberFormatException ex)

...


		{
			return null;
		}
	}
}

Metóda parseInt má rovnaké formálne rozhranie a ja tiež funkčne zhodná s RPC s RPC PROCEDURE E.Service.Parse uvedenou v kapitole 5 4.3.2. Pri jej mapovaní boli použité rovnaké anotácie s rovnakým významom ako na metódu Service.parse.

Rozdiel medzi RPC Parse napísanej v ESL a metódou ExampleHandler.parseInt je v tom, že metódu parseInt nie je možné zavolať asynchrónne. Pre takéto volanie by sa JAPI pokúsilo nájsť druhú metódu s rovnakým formálnym rozhraním, ktoré by malo parameter RPC.asynchronous = true.

...

true.

Kotva
_Toc490141260
_Toc490141260
4.3.4. Použitie anotácie CallerInformation

Blok kódu
languagejava
themeEclipse
import sk.ipesoft.d2000.d2japi.annotations.ParameterType;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.Parameter;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.ParameterValue;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.RPC;

...


import sk.ipesoft.d2000.d2japi.annotations.eventBinding.ReturnValue;

...



public class HelloHandler

...


{

...


	@RPC(name = "Hello")

...


	public void hello(

...


	    @CallerInformation(type = CallerInformationType.processHobj) Integer processHobj,

...


	    @CallerInformation(type = CallerInformationType.eventHobj) Integer eventHobj,

...


	    @CallerInformation(type = CallerInformationType.internalJava) Boolean java)

...


	{
	    ...

...


	}

...


}

Anotácia parametra metódy @CallerInformation indikuje, že za hodnotu parametra má byť dosadená informácia o volajúcom. Hodnota parametra type určuje, aká informácia bude dosadená:

  • processHobj – HOBJ procesu (EVH, HIP, DCC), z ktorého bola RPC zavolaná
  • eventHobj – HOBJ objektu typu Event, z ktorého bola RPC zavolaná.
  • internalJava – nadobúda hodnotu true, ak bola RPC zavolaná z prostredia internej Javy.

Kotva
_Toc490141261
_Toc490141261
4.4. Použitie anotovaných objektov

V kapitolách 5 4.2. a 5 4.3. a ich podkapitolách boli vytvorené definície mapovania štruktúrovaných hodnôt (SD.Person  Person  Person) a definície mapovania volania RPC (Service  E E.Service) a späť (trieda ExampleHandler). Ich použitie zjednodušuje mechanickú prácu vytvárania a konverzie unival hodnôt ako aj potrebu manažovať a opakovane používať množstvo HOBJ pre volanie RPC.

Pri používaní anotácií v jazyku Java je dôležité si uvedomiť, že označenie nejakého objektu anotáciou nemá žiadne priame funkčné dôsledky. Napríklad, ak vytvoríme inštanciu triedy ExampleHandler a následne zavoláme jeho metódu parseInt, jej vykonanie prebehne vždy rovnako, bez ohľadu na prítomnosť alebo neprítomnosť anotácie @RPC. Anotácie slúžia iba na to, aby sa kód, ktorý skúma iné časti kódu, vedel lepšie orientovať.

Nasledujúce príklady sa budú odkazovať na triedy vytvorené v príkladoch v kapitolách 5 4.2.1, 5 4.3.2. a 5 4.3.3. Okrem toho budú použité nasledovné objekty:

Blok kódu
languagejava
themeEclipse
D2Connector connector = ... // aktivne spojenie

...


D2Session session = connector.createSession(... // aktivna session

Na konverzie štruktúrovaných hodnôt bude použitý objekt typu UnivalConvertor prístupný cez connector.getDefaultUnivalConvertor().

Kotva
_Toc490141262
_Toc490141262
4.4.1. Príklad volania z JAPI do ESL

V uvedenom príklade je ukážka volania RPC z prostredia JAPI. Príklad sa skladá z inicializačnej časti (kroky 1 a 2), ktorú je potrebné spraviť raz, pri štarte aplikácie, po pripojení sa ku kernelu. Ďalšie kroky (odrážky), sú príklady samotného volania, je možné použiť v ľubovoľnom poradí a opakovať podľa potreby.

  1. Vytvorenie tzv. Event Proxy Factory objektu. V tomto kroku je trieda Service analyzovaná. Nový objekt (factory) v sebe implementuje mapovanie RPC volaní podľa nájdených anotácií. Parametre volania majú nasledujúci význam:
    • Service.class  referencia   referencia na triedu, ktorá definuje mapovanie
    • session

       získanie

       získanie HOBJ a parent HOBJ

      objektu E.Service

      objektu E.Service

      Blok kódu
      languagejava
      themeEclipse
      EventProxyFactory<Service> factory =EventProxyFactory.createFactory(Service.class, session);


  2. Vytvorenie tzv. Event Proxy objektu s využitím factory z predošlého kroku. V tomto kroku vznikne inštancia anonymnej triedy (odvodenej od java.lang.reflect.Proxy), ktorá implementuje rozhranie Service, aby bolo možné volať anotované metódy. Implementáciu tejto triedy generuje JAPI. Parameter volania má nasledovný význam:
    • session

       asociuje

       asociuje vytvorený objekt proxy s touto inštanciou Session – v jej mene budú RPC volané. Môže to byť iná inštancia, ako v kroku 1.

      Blok kódu
      languagejava
      themeEclipse
      Service proxy = factory.createDefault(session);


Nasledujú príklady samotného volania:

  • Jednoduché volanie RPC Parse:

    Blok kódu
    languagejava
    themeEclipse
    Integer result;

...

  • 
    result = proxy.parse("12"); // Integer.valueOf(12)

...

  • 
    result = proxy.parse("ab"); // null


  • Použitie kontajnera InOut<> vo volaní RPC Square:

    Blok kódu
    languagejava
    themeEclipse
    Double value = 5.0;

...

  • 
    InOut<Double> valueContainer = new InOut<>(value);

...

  • 
    proxy.sqare_2(valueContainer);

...

  • 
    Double result = valueContainer.getValue(); 


V aplikáciách, kde dochádza k viacnásobnému pripájaniu a odpájaniu počas životného cyklu aplikácie:

  • Krok 1 stačí spraviť raz, po vytvorení 1. session. Vzniknutú factory môžete považovať za platnú, pokým je aktívny connector. Pre nový connector je potrebné vytvoriť novú factory.
  • Krok 2 je potrebné raz zopakovať pre každú novú session, z ktorej majú byť volané RPC.

Kotva
_Toc490141263
_Toc490141263

...

4.4.2. Príklad volania z ESL do JAPI

V uvedenom príklade je ukážka volania RPC z prostredia ESL do prostredia JAPI a najmä spôsob spracovania a odpovedania na toto volanie. Príklad sa skladá z inicializačnej časti (kroky 1 a 2), po ktorej bude možné adresovať RPC volania do zvolenej session. Krok 3 je inicializáciou v ESL. Krok 4 je samotné volanie, ktorý možno podľa potreby opakovať s ľubovoľnými parametrami.

  1. Vytvorenie tzv. Event Wrapper Factory objektu. V tomto kroku je trieda ExampleHandler analyzovaná. Nový objekt factory v sebe implementuje spracovanie prichádzajúcich RPC volaní a ich mapovanie na volania metód triedy ExampleHandler. Význam použitých parametrov je nasledovný:
    • ExampleHandler.class  referencia  referencia na triedu, ktorá definuje mapovanie
    • session

       preklad mien

       preklad mien

      Blok kódu
      languagejava
      themeEclipse
      EventWrapperFactory<ExampleHandler> factory = EventWrapperFactory.createFactory(ExampleHandler.class, session);


  2. Registrácia inštancie triedy ExampleHandler pre prijímanie RPC volaní do konkrétnej session. Po tomto kroku bude možné adresovať volanie RPC Parse aj do použitej session.

    Blok kódu
    languagejava
    themeEclipse
    ExampleHandler handler = new ExampleHandler();

...

  1. 
    factory.registerNewHandler(session, handler);


  2. Uloženie HOBJ dynamického objektu session, aby bolo možné neskôr volať späť. V tele ľubovoľnej RPC v ESL je možné zistiť adresu (HOBJ procesu a objektu) volajúceho nasledovným spôsobom:

    Blok kódu
    languageesl
    themeRDark
    INT _sessionHobj

...

  1. 
    RPC PROCEDURE Register

...

  1. 
    _sessionHobj := %GetRPCCallerProcess()

...

  1. 
    END Register
    Značky Wiki



  2. Volanie

    RPC

    z prostredia

    z prostredia ESL.

    Namiesto

    mena

    objektu

    je

    použité

    \

    [(0)

    \

    ]

    pretože

    v

    _

    JAPI

    _

    neexistuje

    ekvivalent

    objektu

    typ

    Event.

    Namiesto

    mena

    procesu

    je

    použité

    (_sessionHobj)

    pretože

    session

    je

    v D2000

    v D2000 DODM

    dynamický

    objekt

    typu

    proces

    a na

    a na jeho

    meno

    sa

    nedá

    použiť

    ako

    identifikátor

    v zdrojovom

    v zdrojovom kóde.

...

  1. Blok kódu
    languageesl
    themeRDark
    INT _r
    CALL 

...

  1. [(0)

...

  1. ] Parse("12", _r) ON (_sessionHobj)

...



...

Kotva
1
1
1 D2000 logická hodnota je štandardne mapovaná vymenovaným typom sk.ipesoft.d2000.base.VBool. Pre zjednodušenie použitia je umožnené mapovať typom java.lang.Boolean, pričom je hodnota vOscillate mapovaná ako false.

...

Kotva
7
7
7 Rovnako v dokumente neuvádzame definíciu a mapovanie pre SD.Metadata, lebo nie je potrebné.

Kotva
8
8
8 Môžu byť volané aj z prostredia internej Javy a tiež z prostredia JAPI.