5. prosince 2012

Custom XSLT funkce v Oracle SOA Suite

Už jste se s tím určitě setkali - nejednoznačnost globální definice boolean. (Globální myslím v rámci SOA napříč všemi systémy.) V každém jazyku je to definované trochu jinak. A proto pokud překládám hodnotu z jednoho systému (nebo rozhraní) na jiný, musím použít nějakou konverzi.

Obecně v tomto problému hodně pomůže kanonický datový model (Cannonical Data Model, CDM), ale pořád se nevyhneme tomu překladu (jenom jich bude méně).

Co jsem teď aktuálně řešil (a že nás to na projektu už nějakou chvilku občas drobně trápí), byl překlad boolean typu z XSD na typ v Oracle databázi. Jak asi víte, Oracle DB nemá typ boolean a nejčastěji se to řeší jako integer 0/1, nebo char Y/N apod. Když tak mě v komentářích opravte - nejsem Oraclista (= databázista).

V XSD je to sice jednoznačnější (viz specifikace boolean), ale záleží, jestli pracujeme s kanonickou (true, false), nebo lexikální (true, false, 1, 0) reprezentací.

Protože se tenhle problém čas od času opakoval, rozhodl jsem se napsat uživatelsky definovanou XSLT funkci pro překlad boolean na integer. Platforma, na které se pohybuji je Oracle SOA Suite.

Definice funkce

Protože celá(?) implementace Oracle SOA Suite je v Javě, tak nepřekvapí, že uživatelská XSLT funkce je taky v Javě:
public class CustomFunctions {

   public static int booleanToInt(String bool) {
      int result = 0;

      if ("true".equals(bool) || "1".equals(bool)) {
         result = 1;
      }

      return result;
   }

}
Jsou tam dvě drobná omezení. (A) Metoda musí být definovaná jako statická. (B) Jak návratová hodnota, tak parametry metody musí být pouze následujících typů:
  • java.lang.String
  • int
  • float
  • double
  • boolean
  • oracle.xml.parser.v2.XMLNodeList
  • oracle.xml.parser.v2.XMLDocumentFragment

Ve výčtu je sice uvedný boolean, ale jak jsem zjistil, v rámci XSLT transformace vstupuje do metody String. Proto je v uvedené metodě v parametru String a ne boolean.

Dále potřebujeme mapovací konfigurační soubor. Musí mít následující jméno a umístění:
META-INF/ext-mapper-xpath-functions-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<soa-xpath-functions version="11.1.1"
       xmlns="http://xmlns.oracle.com/soa/config/xpath"
       xmlns:sws="http://www.oracle.com/XSL/Transform/java/cz.swsamuraj.xslt.CustomFunctions">
   <function name="sws:booleanToInt">
      <className>
          cz.swsamuraj.xslt.CustomFunctions
      </className>
      <return type="number"/>
      <params>
         <param name="boolean" type="string"/>
      </params>
      <desc>Method transforms a boolean value to
          integer. True is converted to 1 and false
          to 0.
      </desc>
      <detail>Method transforms a boolean value to
          integer. True is converted to 1 and false
          to 0.
      </detail>
      <icon>cz/swsamuraj/xslt/Boolean.png</icon>
   </function>
</soa-xpath-functions>
Tady je důležité, aby konfigurační soubor obsahoval namespace, který splňuje následující podmínky. Začíná:
http://www.oracle.com/XSL/Transform/java/

a končí plně kvalifikováným názvem Java třídy, tj.:
cz.swsamuraj.xslt.CustomFunctions

Zbytek je předpokládám zřejmý. Pak už stačí zkompilovat třídu, mapovací soubor a ev. resources (ikona) do JAR souboru.



Nastavení IDE

Aby se dala nová funkce používat v IDE (povinný JDeveloper) je potřeba ji tam zaregistrovat:
  1. Tools -> Preferences -> SOA
  2. Tlačítkem Add přidat připravený JAR soubor.
  3. Restartovat JDeveloper.
Pak již stačí otevřít nějaký XSLT soubor a naši novou funkci najdeme v Component Palette pod položkou User Defined:



Deployment do runtime

Nyní již můžeme novou funkci v IDE vyzkoušet (a otestovat), ale aby fungovala také ve službách je potřeba výše vytvořený JAR soubor dostat také na server (SOA Suita běží na WebLogicu):
  1. JAR soubor nakopírujeme do adresáře <ORACLE_HOME>/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1
  2. V tomto adresáři spustíme příkaz ant.
  3. Restartujeme WebLogic.

Odkazy

Žádné komentáře:

Okomentovat