b'\n_START_ARTICLE_\nN\xc3\xa1vrhov\xc3\xbd vzor Fluid Logic\n_START_PARAGRAPH_\nN\xc3\xa1vrhov\xc3\xbd vzor Fluid Logic byl publikov\xc3\xa1n v d\xc3\xadle Real World Java EE Patterns vydan\xc3\xa9 v roce 2009 Adamem Bienem. Jedn\xc3\xa1 se o n\xc3\xa1vrhov\xc3\xbd vzor vyu\xc5\xbe\xc3\xadvaj\xc3\xadc\xc3\xad se p\xc5\x99i v\xc3\xbdvoji software, kter\xc3\xbd do sebe mus\xc3\xad implementovat prvky dynamick\xc3\xbdch jazyk\xc5\xaf. Vzor byl navr\xc5\xbeen a je prezentov\xc3\xa1n pomoc\xc3\xad programovac\xc3\xadho jazyka Java, kter\xc3\xbd je spustiteln\xc3\xbd v prost\xc5\x99ed\xc3\xad JVM, stejn\xc4\x9b jako i mnoho nov\xc4\x9b vznikaj\xc3\xadc\xc3\xad dynamick\xc3\xbdch jazyk\xc5\xaf.\n_START_SECTION_\nD\xc5\xafvody pro vznik n\xc3\xa1vrhov\xc3\xa9ho vzoru\n_START_PARAGRAPH_\nJava je statick\xc3\xbd jazyk zd\xc5\xafraz\xc5\x88uj\xc3\xadc\xc3\xad siln\xc3\xa9 typov\xc3\xa1n\xc3\xad, proto je vhodn\xc3\xa1 pro implementov\xc3\xa1n\xc3\xad dob\xc5\x99e definovan\xc3\xa9 a stabiln\xc3\xad business logiky. Tento programovac\xc3\xad jazyk v\xc5\xa1ak nen\xc3\xad stav\xc4\x9bn\xc3\xbd na algoritmy, kter\xc3\xa9 se \xc4\x8dasto m\xc4\x9bn\xc3\xad, proto\xc5\xbee ka\xc5\xbed\xc3\xa1 zm\xc4\x9bna aplikace vy\xc5\xbeaduje jej\xc3\xad kompilaci a nov\xc3\xa9 nasazen\xc3\xad do produk\xc4\x8dn\xc3\xadho prost\xc5\x99ed\xc3\xad._NEWLINE_Siln\xc3\xa9 typov\xc3\xa1n\xc3\xad a statick\xc3\xa9 podoba jazyka nese tud\xc3\xad\xc5\xbe i negativa. Pro r\xc5\xafzn\xc3\xa9 \xc3\xba\xc4\x8dely je lep\xc5\xa1\xc3\xad vyu\xc5\xbe\xc3\xadt mo\xc5\xbenost\xc3\xad dynamick\xc3\xbdch jazyk\xc5\xaf ne\xc5\xbe jazyku Java. T\xc4\x9bmito jazyky mohou b\xc3\xbdt nap\xc5\x99\xc3\xadklad JavaScript, Ruby nebo Python. V jazyce Java se n\xc3\xa1m jen st\xc4\x9b\xc5\xbe\xc3\xad poda\xc5\x99\xc3\xad interpretovat business logiku aplikace za jej\xc3\xadm b\xc4\x9bhu. Mohli bychom vyu\xc5\xbe\xc3\xadt r\xc5\xafzn\xc3\xa9 n\xc3\xa1stroje, jako je nap\xc5\x99\xc3\xadklad ANTLR (http://www.antlr.org/), a vytvo\xc5\x99it si vlastn\xc3\xad dom\xc3\xa9nov\xc4\x9b specifick\xc3\xbd jazyk (DSL), kter\xc3\xbd by byl zpracov\xc3\xa1v\xc3\xa1n a interpretov\xc3\xa1n za b\xc4\x9bhu programu. S vytvo\xc5\x99en\xc3\xadm vlastn\xc3\xadho t\xc3\xadmto DSL je v\xc5\xa1ak spojeno obrovsk\xc3\xa9 \xc3\xbasil\xc3\xad ohledn\xc4\x9b designu, testov\xc3\xa1n\xc3\xad a dokumentace.\n_START_SECTION_\nVytvo\xc5\x99en\xc3\xad n\xc3\xa1vrhov\xc3\xa9ho vzoru\n_START_PARAGRAPH_\nProbl\xc3\xa9m s vlo\xc5\xbeen\xc3\xadm vlastn\xc3\xadm skript\xc5\xaf, kter\xc3\xa9 by n\xc3\xa1\xc5\xa1 program mohl dynamicky zpracov\xc3\xa1vat byl vy\xc5\x99e\xc5\xa1en v Java 6 Standard Edition. V Java specifikaci ozna\xc4\x8den\xc3\xa9 jako JSR-223 (Scripting for the Java Platform) je navr\xc5\xbeeno vhodn\xc3\xa9 API, kter\xc3\xa9 n\xc3\xa1m nab\xc3\xadz\xc3\xad interakci s v\xc3\xadce ne\xc5\xbe 100 skriptovac\xc3\xadmi jazyky. Je dokonce mo\xc5\xben\xc3\xa9 vlo\xc5\xbeit java objekt do objektu ScriptEngine a u\xc4\x8dinit ho tak dostupn\xc3\xbdm pro zpracov\xc3\xa1n\xc3\xad dynamick\xc3\xbdm jazykem. Inicializace samotn\xc3\xa9ho ScriptEngine vezme jen p\xc3\xa1r \xc5\x99\xc3\xa1dek k\xc3\xb3du a je uk\xc3\xa1z\xc3\xa1na n\xc3\xad\xc5\xbee na p\xc5\x99\xc3\xadkladu. Pou\xc5\xbeit\xc3\xad skriptovac\xc3\xadch jazyk\xc5\xaf nen\xc3\xad z\xc3\xa1visl\xc3\xa9 na \xc5\xbe\xc3\xa1dn\xc3\xa9m prost\xc5\x99ed\xc3\xad a m\xc5\xaf\xc5\xbee b\xc3\xbdt vyu\xc5\xbeito jak p\xc5\x99\xc3\xadpadech aplikac\xc3\xad, kter\xc3\xa9 mus\xc3\xad b\xc4\x9b\xc5\xbeet v r\xc5\xafzn\xc3\xbdch Java EE kontejnerech, tak v p\xc5\x99\xc3\xadpadech, kde posta\xc4\x8duje nasazen\xc3\xad platformy Java SE. Proto\xc5\xbee n\xc3\xa1vrhov\xc3\xbd vzor \xc3\xbazce souvis\xc3\xad s Java Scripting API, tak proto podrobn\xc4\x9bji vysv\xc4\x9btluji a ukazuji na p\xc5\x99\xc3\xadkladech jeho vyu\xc5\xbeit\xc3\xad, aby bylo jasn\xc4\x9b patrn\xc3\xa9, \xc4\x8deho v\xc5\xa1eho lze implementov\xc3\xa1n\xc3\xadm vzoru Fluid Logic dos\xc3\xa1hnout._NEWLINE__NEWLINE_T\xc5\x99\xc3\xadda Calculator, definovan\xc3\xa1 n\xc3\xad\xc5\xbee v k\xc3\xb3du, je naprogramov\xc3\xa1na tak, aby zpracovala v\xc3\xbdraz p\xc5\x99edan\xc3\xbd jako parametr metod\xc4\x9b calculate._NEWLINE_import javax.script.Bindings;import javax.script.ScriptContext;import javax.script.ScriptEngine;import javax.script.ScriptEngineManager;public class Calculator {_NEWLINE__NEWLINE_    private static final String ENGINE_NAME = "JavaScript";_NEWLINE_    _NEWLINE_    private ScriptEngine scriptEngine = null;_NEWLINE_    _NEWLINE_    private final static double FIVE = 5;_NEWLINE_    _NEWLINE_    public Calculator(){_NEWLINE_        initScripting();_NEWLINE_    }_NEWLINE_    _NEWLINE_    private void initScripting(){_NEWLINE_        ScriptEngineManager engineManager = new ScriptEngineManager();_NEWLINE_        this.scriptEngine = engineManager.getEngineByName(ENGINE_NAME);_NEWLINE_        if(this.scriptEngine == null){_NEWLINE_            throw new IllegalStateException("Cannot create... " + ENGINE_NAME);_NEWLINE_        }_NEWLINE_    }_NEWLINE_    _NEWLINE_    public Object calculate(String formula){_NEWLINE_        Object retVal = null;_NEWLINE_        try {_NEWLINE_            Bindings binding = this.scriptEngine.createBindings();_NEWLINE_            binding.put("FIVE", FIVE);_NEWLINE_            this.scriptEngine.setBindings(binding, ScriptContext.GLOBAL_SCOPE);_NEWLINE_            retVal = this.scriptEngine.eval(formula);_NEWLINE_        } catch (Exception e) {_NEWLINE_            throw new IllegalStateException("Cannot create... " + e, e);_NEWLINE_        }_NEWLINE_        return retVal;_NEWLINE_    }}_NEWLINE_Nyn\xc3\xad si uk\xc3\xa1\xc5\xbeeme, jak t\xc5\x99\xc3\xaddu Calculator vyu\xc5\xbe\xc3\xadt a spustit k\xc3\xb3d z JavaScript v Jav\xc4\x9b pomoc\xc3\xad Java Scripting API. M\xc5\xaf\xc5\xbeete si v\xc5\xa1imnout, \xc5\xbee p\xc5\x99i generov\xc3\xa1n\xc3\xad v\xc3\xbdrazu 2 * 2 * FIVE, jsme vyu\xc5\xbeili konstantu, kterou jsme si ve t\xc5\x99\xc3\xadd\xc4\x9b Calculator nadefinovali a vlo\xc5\xbeili do skriptov\xc3\xa9ho kontextu._NEWLINE_public class App {_NEWLINE_    public static void main( String[] args ){_NEWLINE_        Calculator cal = new Calculator();_NEWLINE_        System.out.println("V\xc3\xbdsledek v\xc3\xbdpo\xc4\x8dtu je " + _NEWLINE_                           cal.calculate("2 * 2 * FIVE"));_NEWLINE_    }}_NEWLINE_Jak jsme ji\xc5\xbe napsali d\xc5\x99\xc3\xadve, n\xc3\xa1vrhov\xc3\xbd vzor Fluid Logic je vhodn\xc3\xbd zejm\xc3\xa9na pro jeho mo\xc5\xbenost jednoduch\xc3\xa9ho p\xc5\x99em\xc3\xadst\xc4\x9bn\xc3\xad dynamick\xc3\xa9ho k\xc3\xb3du nebo jeho zm\xc4\x9bny. K\xc3\xb3d m\xc5\xaf\xc5\xbee b\xc3\xbdt nahr\xc3\xa1n z mnoha zdroj\xc5\xaf. V dal\xc5\xa1\xc3\xad \xc4\x8d\xc3\xa1sti si uk\xc3\xa1\xc5\xbeeme, jak m\xc5\xaf\xc5\xbee b\xc3\xbdt k\xc3\xb3d dynamicky nahr\xc3\xa1n ze souboru, jsou v\xc5\xa1ak mo\xc5\xben\xc3\xa9 i jin\xc3\xa9 varianty, nap\xc5\x99\xc3\xadklad nahr\xc3\xa1n\xc3\xad k\xc3\xb3du ulo\xc5\xbeen\xc3\xa9ho v datab\xc3\xa1zi nebo ze vzd\xc3\xa1len\xc3\xa9ho souboru um\xc3\xadst\xc4\x9bn\xc3\xa9ho na s\xc3\xadti.\n_START_SECTION_\nZp\xc5\xafsob nahr\xc3\xa1n\xc3\xad k\xc3\xb3du ze souboru\n_START_PARAGRAPH_\nNyn\xc3\xad uk\xc3\xa1\xc5\xbeu, jak je mo\xc5\xben\xc3\xa9 nahr\xc3\xa1t dynamicky k\xc3\xb3d ze souboru a nechat ho zpracovat pomoc\xc3\xad Java Scripting API. Znovu se jedn\xc3\xa1 o k\xc3\xb3d napsan\xc3\xbd v JavaScriptu._NEWLINE_// Vytvo\xc5\x99\xc3\xadme engine managerScriptEngineManager engineManager = new ScriptEngineManager();// Vytvo\xc5\x99\xc3\xadme konkr\xc3\xa9tn\xc3\xad JavaScript engineScriptEngine scriptEngine = engineManager.getEngineByName("JavaScript");// Pomoc\xc3\xad JavaScript enginu zpracujeme soubor s k\xc3\xb3demscriptEngine.eval(new FileReader("soubor.js"));\n_START_SECTION_\nZavol\xc3\xa1n\xc3\xad konkr\xc3\xa9tn\xc3\xad funkce\n_START_PARAGRAPH_\nDal\xc5\xa1\xc3\xad p\xc5\x99\xc3\xadklad n\xc3\xa1m ukazuje, jak je mo\xc5\xben\xc3\xa9 vytvo\xc5\x99it metodu a pot\xc3\xa9 j\xc3\xad opakovan\xc4\x9b volat pomoc\xc3\xad rozhran\xc3\xad Invocable._NEWLINE_String script = "function hello(name) { print(\'Hello, \' + name); }";scriptEngine.eval(script);// javax.script.Invocable je voliteln\xc3\xa9 rozhran\xc3\xad.// P\xc5\x99ed pou\xc5\xbeit\xc3\xadm mus\xc3\xadme zkontrolovat, jestli n\xc3\xa1\xc5\xa1 engine rozhran\xc3\xad implementuje!// JavaScript toto rozhran\xc3\xad implementuje.Invocable inv = (Invocable) engine;// Zavol\xc3\xa1n\xc3\xad funkce hello s parametrem nameinv.invokeFunction("hello", "Java Scripting API");\n_START_SECTION_\nVol\xc3\xa1n\xc3\xad metod na objektech\n_START_PARAGRAPH_\nPokud n\xc3\xa1mi zvolen\xc3\xbd dynamick\xc3\xbd jazyk podporuje objektov\xc4\x9b orientovan\xc3\xa9 programov\xc3\xa1n\xc3\xad, tak je mo\xc5\xben\xc3\xa9 vyu\xc5\xbeit\xc3\xad objekt\xc5\xaf i pomoc\xc3\xad Java Scripting API._NEWLINE_// Pomoc\xc3\xad JavaScriptu vytvo\xc5\x99\xc3\xadme objekt s metodou helloString script = "var obj = new Object();"; _NEWLINE_script += "obj.hello = function(name) { print(\'Hello, \' + name); }";_NEWLINE_        _NEWLINE_scriptEngine.eval(script);Invocable inv = (Invocable) scriptEngine;// Z\xc3\xadsk\xc3\xa1me objekt, na kter\xc3\xa9m chceme volat metoduObject obj = scriptEngine.get("obj");// Zavol\xc3\xa1me metodu "hello" na objektu "obj" s dan\xc3\xbdm parametreminv.invokeMethod(obj, "hello", "Java Scripting API" );\n_START_SECTION_\nImplementace rozhran\xc3\xad\n_START_PARAGRAPH_\nDal\xc5\xa1\xc3\xad p\xc5\x99\xc3\xadklad n\xc3\xa1m uk\xc3\xa1\xc5\xbee jak m\xc5\xaf\xc5\xbeeme vz\xc3\xadt objekt ze skriptovac\xc3\xadho jazyka a pou\xc5\xbe\xc3\xadt ho jako implementaci javovsk\xc3\xa9ho rozhran\xc3\xad._NEWLINE_String script = "var obj = new Object();";script += "obj.run = function() { println(\'run method called\'); }";_NEWLINE_        _NEWLINE_scriptEngine.eval(script);Object obj = scriptEngine.get("obj");Invocable inv = (Invocable) scriptEngine;// Z\xc3\xadskan\xc3\xbd objekt vlo\xc5\xbe\xc3\xadme jako implementaci "Runnable" rozhran\xc3\xadRunnable r = inv.getInterface(obj, Runnable.class);// Vytvo\xc5\x99\xc3\xadme nov\xc3\xa9 vl\xc3\xa1kno s implementac\xc3\xad ze skriptovac\xc3\xadho jazykaThread th = new Thread(r);th.start();\n_START_SECTION_\nVyu\xc5\xbeit\xc3\xad java t\xc5\x99\xc3\xadd ve skriptovac\xc3\xadm jazyce\n_START_PARAGRAPH_\nPosledn\xc3\xad p\xc5\x99\xc3\xadklad ukazuje na vyu\xc5\xbeit\xc3\xad javovsk\xc3\xbdch t\xc5\x99\xc3\xadd ve skritovac\xc3\xadm jazyce. Na p\xc5\x99\xc3\xadkladu je zdrojov\xc3\xbd k\xc3\xb3d z JavaScriptu, kter\xc3\xbd n\xc3\xa1sledn\xc4\x9b lze snadno nahr\xc3\xa1t jako souboru a spustit ho. V\xc3\xbdsledkem bude vytvo\xc5\x99en\xc3\xad okna a vyps\xc3\xa1n\xc3\xad \xe2\x80\x9ehello\xe2\x80\x9c na standardn\xc3\xad v\xc3\xbdstup._NEWLINE_importPackage(java.awt);importClass(java.awt.Frame);var frame = new java.awt.Frame("hello");frame.setVisible(true);print(frame.title);\n_START_SECTION_\nDal\xc5\xa1\xc3\xad podporovan\xc3\xa9 dynamick\xc3\xa9 jazyky\n_START_PARAGRAPH_\nP\xc5\x99\xc3\xadklad dal\xc5\xa1\xc3\xadch podporovan\xc3\xbdch dynamick\xc3\xbdch jazyk\xc5\xaf, kter\xc3\xa9 maj\xc3\xad vytvo\xc5\x99eny sv\xc5\xafj ScriptEngine, tud\xc3\xad\xc5\xbe mohou interpretov\xc3\xa1ny a st\xc3\xa1t se tak sou\xc4\x8d\xc3\xa1st\xc3\xad business logiky aplikace._NEWLINE__NEWLINE_JRuby, Groovy, BeanShell, JACL, Jaskell, Java_NEWLINE__NEWLINE_Jawk, Jelly, JEXL, Javascript, Jython, OGNL_NEWLINE__NEWLINE_EEP, xPath, XSLT, Pnuts, Scheme, sl'