Java scripting api
Upcoming SlideShare
Loading in...5
×
 

Java scripting api

on

  • 1,930 views

Présentation donnée par Franck SIMON dans le cadre de ConFoo 2012

Présentation donnée par Franck SIMON dans le cadre de ConFoo 2012

Statistics

Views

Total Views
1,930
Views on SlideShare
1,923
Embed Views
7

Actions

Likes
0
Downloads
38
Comments
0

3 Embeds 7

http://localhost 4
http://www.php-talks.com 2
http://nodeslide.herokuapp.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Java scripting api Java scripting api Presentation Transcript

  • Java Scripting API v 1.0
  • Qui avez-vous en face de vous ? Moi -nom = "SIMON" -prenom = "Franck" -formation = "Ingénieur" -profession = {"développeur","formateur","consultant"} -aime = {"coder","technologie","bandes dessinées","musique"} -email = "franck.simon@free.fr" -web = "http://www.franck-simon.com"Franck SIMON Confoo 2012 - Java Scripting API 2 / 48
  • Qui avez-vous en face de vous ? ● Mes activités ● développement – pour de petites structures ● formation / tutorat ● spécialisé dans la valorisation des tickets dappels – dans le monde des opérateurs telecom virtuels ● Passionné de code ● et toujours émerveilléFranck SIMON Confoo 2012 - Java Scripting API 3 / 48
  • Langages de script ● Facilité dutilisation ● typage dynamique, conversion de type automatique ● Développement rapide de prototypes ● Création dextensions dapplication ● script de configuration ● encapsulation de règles métiers ● programmation par lutilisateur de lapplicationFranck SIMON Confoo 2012 - Java Scripting API 4 / 48
  • Java Scripting API ● API apparue avec Java SE 6 ● API développée sous la JSR 223 ● JSR 223 : Scripting for the Java Platform – JSR : Java Specification Request ● définit une interface dinteraction avec les moteurs de scripts ● classes, interfaces et exceptions réunies dans le package javax.scriptFranck SIMON Confoo 2012 - Java Scripting API 5 / 48
  • Java Scripting API ● Limplémentation Sun utilise le projet Rhino de Mozilla ● http://www.mozilla.org/rhino/ ● certaines fonctionnalités de Rhino nont pas été portées dans limplémentation Sun ● Lutilitaire jrunscript permet de lancer des scripts en mode console ● outil "expérimental" sous les versions 6 et 7 de Java SEFranck SIMON Confoo 2012 - Java Scripting API 6 / 48
  • Étapes dutilisation en Java ● Lobjectif est de faire interpréter un script JavaScript par le moteur de script ● le JavaScript est un flux texte ou un String ● Pour évaluer le JavaScript en Java ● créer une instance de ScriptEngineManager ● récupérer un ScriptEngine ● faire évaluer le script par la méthode eval(...)Franck SIMON Confoo 2012 - Java Scripting API 7 / 48
  • Premier exemple ● Lincontournable "Hello, world" package confoo; import javax.script.*; public class HelloWorld { public static void main(String[] args) throws Exception { String javaScript = "print(Hello, world)"; ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); engine.eval(javaScript); } }Franck SIMON Confoo 2012 - Java Scripting API 8 / 48
  • Les classes et interface de lAPI ● Lensemble des interfaces et classes qui composent lAPI fournit un framework dutilisation des moteurs de script en Java ● 6 interfaces ● 5 classes ● 1 classe dexception ● Les plus utiles ● ScriptEngine : interaction avec le moteur de script ● ScriptEngineManager : point dentrée de lAPIFranck SIMON Confoo 2012 - Java Scripting API 9 / 48
  • La classe ScriptEngineManager ● Point dentrée de lAPI ● Découvre et instancie les fabriques de script ● JavaScript en standard ● Possède des méthodes pour récupérer ● les méta données du moteur de script – langage, version, etc. ● un moteur de script de script par le nom du langage, le type MIME ● Maintient un un contexte global ● contient des entrées clé/valeurFranck SIMON Confoo 2012 - Java Scripting API 10 / 48
  • La classe ScriptEngineManager ● Plusieurs méthodes permettent dobtenir un moteur de script (ScriptEngine) ● par lextension : getEngineByExtension ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByExtension("js"); ● par lalias: getEngineByName ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("ECMAScript"); ● par le type MIME : getEngineByMimeType ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByMimeType("application/javascript");Franck SIMON Confoo 2012 - Java Scripting API 11 / 48
  • La classe ScriptEngineManager ● Des méthodes supplémentaire permettent ● dinscrire dynamiquement de nouveaux moteurs de script – void registerEngineName(String name, ScriptEngineFactory factory) – void registerEngineMimeType(String name, ScriptEngineFactory factory) – void registerEngineExtension(String name, ScriptEngineFactory factory) ● dajouter des paire clé/valeur au contexte globalFranck SIMON Confoo 2012 - Java Scripting API 12 / 48
  • La classe ScriptEngineFactory ● Il est possible pour chaque moteur de script de récupérer ● le nom et la version du moteur ● lextension ● le nom du langage et sa version ● les types MIME ● les alias ● Cf. ScriptEngineFactoryMetaDatas.javaFranck SIMON Confoo 2012 - Java Scripting API 13 / 48
  • La classe ScriptEngineFactory ... ScriptEngineManager manager = new ScriptEngineManager(); List<ScriptEngineFactory> factories = manager.getEngineFactories(); for (ScriptEngineFactory factory : factories) { System.out.println("Nom complet du moteur de script : " + factory.getEngineName()); System.out.println("Version du moteur de script : " + factory.getEngineVersion()); System.out.println("Extensions :"); List<String> extensions = factory.getExtensions(); for (String extension : extensions) System.out.println(" " + extension); System.out.println("Langage : " + factory.getLanguageName()); System.out.println("Version du langage : " + factory.getLanguageVersion()); System.out.println("Types MIME :"); List<String> mimetypes = factory.getMimeTypes(); for (String mimetype : mimetypes) System.out.println(" " + mimetype); System.out.println("Alias :"); List<String> shortnames = factory.getNames(); for (String shortname : shortnames) System.out.println(" " + shortname); System.out.println(); } ...Franck SIMON Confoo 2012 - Java Scripting API 14 / 48
  • Évaluation du script ● Lévaluation du script est effectuée sur linstance de ScriptEngine récupérée ● Plusieurs signatures de la méthode eval(...) permettent lévaluation : ● du script en tant que String ● du script lu dans un flux de type Reader ● un contexte de script peut y être associé ● eval(...) retourne le résultat de lévaluation sous forme dObject ● null si pas de résultatFranck SIMON Confoo 2012 - Java Scripting API 15 / 48
  • Évaluation dun String ● Exemple EvalString.java public class EvalString { public static void main(String[] args) throws ScriptException{ String script = "2+2"; ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); Object o = engine.eval(script); System.out.println(o); } }Franck SIMON Confoo 2012 - Java Scripting API 16 / 48
  • Évaluation dun Reader ● Exemple EvalReader.java public class EvalReader { public static void main(String[] args) throws ScriptException,FileNotFoundException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); engine.eval(new FileReader("javascript_01.js")); } } print("Hello, world");Franck SIMON Confoo 2012 - Java Scripting API 17 / 48
  • Communication entre Java etJavaScript ● Des objets Java peuvent être passés au script ● JavaScript peut alors utiliser les membres publiques des objets exposés ● void put(String key, Object value) passe un objet au moteur de script – méthode de ScriptEngine ● la méthode Object get(String key) permet à Java de récupérer des variable du script – méthode de ScriptEngineFranck SIMON Confoo 2012 - Java Scripting API 18 / 48
  • Utilisation dun objet Java parJavaScript ● Exemple UtilisationPoint_01.java public class UtilisationPoint_01 { public static void main(String[] args) throws FileNotFoundException, ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); Point p = new Point(1,2); engine.put("p1", p); engine.eval(new FileReader("point_01.js")); association pour utilisation } par JavaScript } var x = p1.getX(); var y = p1.getY(); print("le point se trouve en ("+x+","+y+")");Franck SIMON Confoo 2012 - Java Scripting API 19 / 48
  • Utilisation dun objet Java parJavaScript ● JavaScript peut donc changer létat de notre Point ● Exemple UtilisationPoint_02.java public class UtilisationPoint_02 { public static void main(String[] args) throws FileNotFoundException, ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); Point p = new Point(1,2); engine.put("p1", p); engine.eval(new FileReader("point_02.js")); System.out.println(p); } } p1.setX(110) ;Franck SIMON Confoo 2012 - Java Scripting API 20 / 48
  • Récupération de variables JavaScript ● Exemple RecuperationVariables_01.java public class RecuperationVariables_01 { public static void main(String[] args) throws FileNotFoundException, ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); engine.eval(new FileReader("variables_01.js")); String message = (String) engine.get("message"); System.out.println("message : "+message); double d = (Double) engine.get("dimension"); System.out.println("dimension : "+d); List<String> liste = (List<String>) engine.get("liste"); for(String ville : liste) System.out.println(ville); } } var message = "Hello, world"; var dimension = 10.3; var liste = ["Montréal","Saint-Malo","Paris"];Franck SIMON Confoo 2012 - Java Scripting API 21 / 48
  • Invoquer des fonctions JavaScript enJava ● Un des intérêts de dutiliser JavaScript dans un programme Java est dutiliser des fonctions JavaScript ● créées par dautres développeur ● ou des "utilisateurs avertis" ● valable aussi pour des objets JavaScriptFranck SIMON Confoo 2012 - Java Scripting API 22 / 48
  • Invoquer des fonctions JavaScript enJava ● Le moteur de script doit implémenter linterface Invocable de lAPI ● rhino implémente Invocable ● Permet linvocation depuis Java de fonctions du script ● ou méthodes dobjet JavaScript ● Permet au script dimplémenter des interfaces Java ● et là cela devient très intéressantFranck SIMON Confoo 2012 - Java Scripting API 23 / 48
  • Invoquer des fonctions JavaScript enJava ● Schéma de codage de linvocation de fonctions JavaScript en Java ● récupérer un ScriptEngine ● évaluer le script ● caster le ScriptEngine en Invocable ● appeler la méthode invokeFunction sur le Invocable – ou invokeMethod pour un objet JavaScript – une exception NoSuchMethodException est susceptible dêtre levéeFranck SIMON Confoo 2012 - Java Scripting API 24 / 48
  • Invoquer des fonctions JavaScript enJava ● Exemple InvoqueJavaScript_01.java public class InvoqueJavaScript_01 { public static void main(String[] args) throws FileNotFoundException, ScriptException, NoSuchMethodException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.eval(new FileReader("fonctions_01.js")); Invocable invocable = (Invocable) engine; double r = (Double) invocable.invokeFunction("somme", 10,20); System.out.println("Résulat r : "+r); } } function somme(i,j){ return i+j; }Franck SIMON Confoo 2012 - Java Scripting API 25 / 48
  • Invoquer des fonctions JavaScript enJava ● Invoquer une fonction JavaScript avec un nombre variable de paramètres ● Exemple InvoqueJavaScript_02.java ... engine.eval(new FileReader("fonctions_01.js")); Invocable invocable = (Invocable) engine; double r = (Double) invocable.invokeFunction("add", 10,20); System.out.println("Résulat r : "+r); ... function add(){ var res = 0; for(var i=0 ; i<arguments.length; i++){ res = res + arguments[i]; } return res; }Franck SIMON Confoo 2012 - Java Scripting API 26 / 48
  • Invoquer des méthodes dobjetsJavaScript en Java ● Exemples InvoqueJavaScript_03.java...engine.eval(new FileReader("fonctions_01.js"));Invocable invocable = (Invocable) engine;Object voiture = engine.get("voiture");invocable.invokeMethod(voiture, "rouler");invocable.invokeMethod(voiture, "atteindre", 130);System.out.println("Nb de chevaux : "+ invocable.invokeMethod(voiture, "getNbChevaux"));... var voiture = new Object(); voiture.getNbChevaux=function(){return 5;} voiture.rouler = function(){println(Je roule !!!!);} voiture.atteindre=function(vitesse){ println("Accélération jusquà "+vitesse+" km/h");}Franck SIMON Confoo 2012 - Java Scripting API 27 / 48
  • Implémenter des interfaces Java enJavaScript ● Les interfaces fournissent une couche abstraite ● Il peut être intéressant de sortir un traitement de la couche Java pour limplémenter en JavaScript ● code métier changeant ● Java fournit linterface et JavaScript limplémentation ● par des fonctions ● par des méthodes dobjetsFranck SIMON Confoo 2012 - Java Scripting API 28 / 48
  • Implémenter des interfaces Java enJavaScript ● Comme pour linvocation depuis Java de fonctions JavaScript, il faut que le moteur de script implémente Invocable ● La méthode getInterface renvoie une implémentation dune interface Java avec les fonctions trouvées par linterpréteurFranck SIMON Confoo 2012 - Java Scripting API 29 / 48
  • Implémenter des interfaces Java enJavaScript ● Linterface Calculable public interface Calculable { int add(int a, int b); } ● Limplémentation en JavaScript ● fichier implementations_01.js function add(a,b){ return a+b;}Franck SIMON Confoo 2012 - Java Scripting API 30 / 48
  • Implémenter des interfaces Java enJavaScript ● Lutilisation de limplémentation en Java ● fichier ImplementationJavaScript_01.java ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.eval(new FileReader("implementations_01.js")); Invocable invocable = (Invocable) engine; Calculable calculable = invocable.getInterface(Calculable.class); System.out.println(calculable.add(10,20));Franck SIMON Confoo 2012 - Java Scripting API 31 / 48
  • Implémenter des interfaces Java enJavaScript ● Si limplémentation utilise un objet JavaScript il faut dabord le retrouver ● implémentation JavaScript – fichier implementations_01.js var calcul = new Object(); calcul.add = function(a,b){return a+b;} ● utilisation en Java – fichier ImplementationJavaScript_01.java engine.eval(new FileReader("implementations_01.js")); Invocable invocable = (Invocable) engine; Object obj = engine.get("calcul"); Calculable calculable = invocable.getInterface(obj,Calculable.class); System.out.println(calculable.add(10,20));Franck SIMON Confoo 2012 - Java Scripting API 32 / 48
  • Import Java dans JavaScript ● Par la fonction importPackage de JavaScript ● moteur rhino ● le nom du package correspond à son import entier – importPackage(java.util) ; ● correspond à un – import java.util.* ; ● java.lang nest pas importé par défaut ● Par la fonction importClass de JavaScript ● Attention les noms de packages doivent suivre la spécification JavaFranck SIMON Confoo 2012 - Java Scripting API 33 / 48
  • Import Java dans JavaScript ● Fichier JavaScript import_01.js importPackage(java.awt); var frame = new java.awt.Frame("Hello"); frame.setVisible(true); ● Exécution du fichier en Java public class EvalReaderImport_01 { public static void main(String[] args) throws ScriptException, FileNotFoundException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); engine.eval(new FileReader("import_01.js")); } }Franck SIMON Confoo 2012 - Java Scripting API 34 / 48
  • Import Java dans JavaScript ● le moteur de script rhino propose aussi un JavaImporter ● fichier import_02.js var gui = new JavaImporter(java.awt); with(gui){ var frame = new Frame("Bonjour"); frame.setVisible(true); }Franck SIMON Confoo 2012 - Java Scripting API 35 / 48
  • Résolution de la surcharge ● Le langage Java supporte la surcharge par les arguments dune méthode ● signatures différentes dun même nom de méthode ● la résolution de lappel est alors effectuée lors de la compilation ● Lors de lappel de méthodes Java depuis un JavaScript le moteur sélectionne la méthode appropriée ● une exception est levée si aucune méthode nest trouvéeFranck SIMON Confoo 2012 - Java Scripting API 36 / 48
  • Utilisation de plusieurs contextes descript ● Dans le exemples précédents les objets Java ont étés exposés à JavaScript dans le contexte par défaut ● Deux contextes existent par défaut ● un contexte global partagé par tous les moteurs qui seront instanciés par le même EngineFactory – ScriptContext.GLOBAL_SCOPE ● un contexte par moteur de script – ScriptContext.ENGINE_SCOPEFranck SIMON Confoo 2012 - Java Scripting API 37 / 48
  • Utilisation de plusieurs contextes descript ● Exemple de manipulation de contexte public class MultiScope { public static void main(String[] args) throws ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine1 = factory.getEngineByName("javascript"); ScriptEngine engine2 = factory.getEngineByName("javascript"); ScriptContext context = new SimpleScriptContext(); Bindings globalScope = engine1.getBindings(ScriptContext.GLOBAL_SCOPE); String script = "println(x : +x)"; globalScope.put("x", "Bonjour"); … // suite page suivanteFranck SIMON Confoo 2012 - Java Scripting API 38 / 48
  • Utilisation de plusieurs contextes descript ● Exemple de manipulation de contexte … // cf. page précédente globalScope.put("x", "Bonjour"); engine1.eval(script); engine2.eval(script); System.out.println("======================"); engine1.put("x", "Hello"); engine1.eval(script); engine2.eval(script); System.out.println("======================"); engine1.eval(script,engine1.getBindings(ScriptContext.GLOBAL_SCOPE)); engine2.eval(script); } }Franck SIMON Confoo 2012 - Java Scripting API 39 / 48
  • Exemple du "monde réel"Et maintenant... … un peu de code pour grande personneFranck SIMON Confoo 2012 - Java Scripting API 40 / 48
  • Exemple : le pattern Visitor ● Lobjectif du modèle de conception Visitor est de séparer un modèle de données de ses traitements ● le modèle de données est souvent structuré en composite ● les traitements peuvent être enrichis sans modifier le modèle de données ● les données doivent "accepter" la visite dun "visiteur" ● cest le visiteur qui effectue le traitement en fonction du type concret de la donnéeFranck SIMON Confoo 2012 - Java Scripting API 41 / 48
  • Exemple : le pattern Visitor ● Ce modèle de conception est très utile si ● la structure des données est stable ● la structure de données est figée – les données et leurs traitements sont séparés – lévolution des traitements est indépendant des données ● Voici la structure extraite de louvrage du GoF ● Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides ● "Design Patterns – Elemnts of Reusable Object-Oriented Software" en 1995Franck SIMON Confoo 2012 - Java Scripting API 42 / 48
  • Exemple : le pattern Visitor ● Diagramme issu du livre du GoFFranck SIMON Confoo 2012 - Java Scripting API 43 / 48
  • Exemple : le pattern Visitor ● Le diagramme de notre exempleFranck SIMON Confoo 2012 - Java Scripting API 44 / 48
  • Exemple : le pattern Visitor ● Linterface Visitor et son implémentation en JavaScriptpublic interface Visitor { var visitor = new Object(); void visitText(Text t); visitor.visitText = function(objText){ void visitLine(Line l); println(objText.getText()); void visitPanel(Panel p); }} visitor.visitLine=function(objLine){ println(objLine.getLongueur()); } visitor.visitPanel=function(objPanel){ println(objPanel.getType()); var liste =objPanel.getElements(); for(var i=0 ; i < liste.size() ; i++){ liste.get(i).accept(visitor) } }Franck SIMON Confoo 2012 - Java Scripting API 45 / 48
  • Exemple : le pattern Visitor ● Mise en œuvre en Java...ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("javascript");engine.eval(new FileReader("visitors.js")); on récupère lobjet JavaScriptObject o = engine.get("visitor");Invocable invocable = (Invocable) engine;Visitor visitor = invocable.getInterface(o, Visitor.class);engine.put("visitor", visitor);p3.accept(visitor); Java voit lobjet JavaScript comme... implémentation de Visitor Pour que le moteur JavaScript puisse caster lobjet en VisitorFranck SIMON Confoo 2012 - Java Scripting API 46 / 48
  • Pour aller plus loin ● Web ● documentation officielle – http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html ● documentation mozilla – projet rhino –http://www.mozilla.org/rhino/ ● Livres ● Beginning Java SE 6 Platform – auteur : Jeff FRIESEN – éditeur : ApressFranck SIMON Confoo 2012 - Java Scripting API 47 / 48
  • Et voilà !!!Franck SIMON Confoo 2012 - Java Scripting API 48 / 48
  • Java Scripting API v 1.0
  • Qui avez-vous en face de vous ? Moi -nom = "SIMON" -prenom = "Franck" -formation = "Ingénieur" -profession = {"développeur","formateur","consultant"} -aime = {"coder","technologie","bandes dessinées","musique"} -email = "franck.simon@free.fr" -web = "http://www.franck-simon.com"Franck SIMON Confoo 2012 - Java Scripting API 2 / 48
  • Qui avez-vous en face de vous ? ● Mes activités ● développement – pour de petites structures ● formation / tutorat ● spécialisé dans la valorisation des tickets dappels – dans le monde des opérateurs telecom virtuels ● Passionné de code ● et toujours émerveilléFranck SIMON Confoo 2012 - Java Scripting API 3 / 48
  • Langages de script ● Facilité dutilisation ● typage dynamique, conversion de type automatique ● Développement rapide de prototypes ● Création dextensions dapplication ● script de configuration ● encapsulation de règles métiers ● programmation par lutilisateur de lapplicationFranck SIMON Confoo 2012 - Java Scripting API 4 / 48
  • Java Scripting API ● API apparue avec Java SE 6 ● API développée sous la JSR 223 ● JSR 223 : Scripting for the Java Platform – JSR : Java Specification Request ● définit une interface dinteraction avec les moteurs de scripts ● classes, interfaces et exceptions réunies dans le package javax.script Franck SIMON Confoo 2012 - Java Scripting API 5 / 48Il existait déjà des solution pour scrypter la plateforme Java avec des langages de script : Groovy, JRuby, Jython, ...
  • Java Scripting API ● Limplémentation Sun utilise le projet Rhino de Mozilla ● http://www.mozilla.org/rhino/ ● certaines fonctionnalités de Rhino nont pas été portées dans limplémentation Sun ● Lutilitaire jrunscript permet de lancer des scripts en mode console ● outil "expérimental" sous les versions 6 et 7 de Java SE Franck SIMON Confoo 2012 - Java Scripting API 6 / 48Pour des raisons de sécurité et dempreinte mémoire, les fonctionnalités suivantes nont pas été portées●le compilateur javascript vers byte-code ("optimizer") na pas été repris, le javascript fonctionne donc toujours en mode interprété●le JavaAdapter de Rhino a été remplacé par une implémentation Sun. Limplémentation Rhino permet à une classe Java dêtre étendue en JavaScript et une interface Java dêtre implémentée en JavaScript, Limplémentation de Sun ne permet que limplémentation dune interface Java en JavaScript●E4X (ECMAScript for XML) a été excus●loutil de commande en ligne Rhino a été remplacé par jrunscript
  • Étapes dutilisation en Java ● Lobjectif est de faire interpréter un script JavaScript par le moteur de script ● le JavaScript est un flux texte ou un String ● Pour évaluer le JavaScript en Java ● créer une instance de ScriptEngineManager ● récupérer un ScriptEngine ● faire évaluer le script par la méthode eval(...)Franck SIMON Confoo 2012 - Java Scripting API 7 / 48
  • Premier exemple ● Lincontournable "Hello, world" package confoo; import javax.script.*; public class HelloWorld { public static void main(String[] args) throws Exception { String javaScript = "print(Hello, world)"; ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("JavaScript"); engine.eval(javaScript); } }Franck SIMON Confoo 2012 - Java Scripting API 8 / 48
  • Les classes et interface de lAPI ● Lensemble des interfaces et classes qui composent lAPI fournit un framework dutilisation des moteurs de script en Java ● 6 interfaces ● 5 classes ● 1 classe dexception ● Les plus utiles ● ScriptEngine : interaction avec le moteur de script ● ScriptEngineManager : point dentrée de lAPIFranck SIMON Confoo 2012 - Java Scripting API 9 / 48
  • La classe ScriptEngineManager ● Point dentrée de lAPI ● Découvre et instancie les fabriques de script ● JavaScript en standard ● Possède des méthodes pour récupérer ● les méta données du moteur de script – langage, version, etc. ● un moteur de script de script par le nom du langage, le type MIME ● Maintient un un contexte global ● contient des entrées clé/valeurFranck SIMON Confoo 2012 - Java Scripting API 10 / 48
  • La classe ScriptEngineManager ● Plusieurs méthodes permettent dobtenir un moteur de script (ScriptEngine) ● par lextension : getEngineByExtension ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByExtension("js"); ● par lalias: getEngineByName ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("ECMAScript"); ● par le type MIME : getEngineByMimeType ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByMimeType("application/javascript");Franck SIMON Confoo 2012 - Java Scripting API 11 / 48
  • La classe ScriptEngineManager ● Des méthodes supplémentaire permettent ● dinscrire dynamiquement de nouveaux moteurs de script – void registerEngineName(String name, ScriptEngineFactory factory) – void registerEngineMimeType(String name, ScriptEngineFactory factory) – void registerEngineExtension(String name, ScriptEngineFactory factory) ● dajouter des paire clé/valeur au contexte globalFranck SIMON Confoo 2012 - Java Scripting API 12 / 48
  • La classe ScriptEngineFactory ● Il est possible pour chaque moteur de script de récupérer ● le nom et la version du moteur ● lextension ● le nom du langage et sa version ● les types MIME ● les alias ● Cf. ScriptEngineFactoryMetaDatas.javaFranck SIMON Confoo 2012 - Java Scripting API 13 / 48
  • La classe ScriptEngineFactory ... ScriptEngineManager manager = new ScriptEngineManager(); List<ScriptEngineFactory> factories = manager.getEngineFactories(); for (ScriptEngineFactory factory : factories) { System.out.println("Nom complet du moteur de script : " + factory.getEngineName()); System.out.println("Version du moteur de script : " + factory.getEngineVersion()); System.out.println("Extensions :"); List<String> extensions = factory.getExtensions(); for (String extension : extensions) System.out.println(" " + extension); System.out.println("Langage : " + factory.getLanguageName()); System.out.println("Version du langage : " + factory.getLanguageVersion()); System.out.println("Types MIME :"); List<String> mimetypes = factory.getMimeTypes(); for (String mimetype : mimetypes) System.out.println(" " + mimetype); System.out.println("Alias :"); List<String> shortnames = factory.getNames(); for (String shortname : shortnames) System.out.println(" " + shortname); System.out.println(); } ...Franck SIMON Confoo 2012 - Java Scripting API 14 / 48
  • Évaluation du script ● Lévaluation du script est effectuée sur linstance de ScriptEngine récupérée ● Plusieurs signatures de la méthode eval(...) permettent lévaluation : ● du script en tant que String ● du script lu dans un flux de type Reader ● un contexte de script peut y être associé ● eval(...) retourne le résultat de lévaluation sous forme dObject ● null si pas de résultatFranck SIMON Confoo 2012 - Java Scripting API 15 / 48
  • Évaluation dun String ● Exemple EvalString.java public class EvalString { public static void main(String[] args) throws ScriptException{ String script = "2+2"; ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); Object o = engine.eval(script); System.out.println(o); } }Franck SIMON Confoo 2012 - Java Scripting API 16 / 48
  • Évaluation dun Reader ● Exemple EvalReader.java public class EvalReader { public static void main(String[] args) throws ScriptException,FileNotFoundException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); engine.eval(new FileReader("javascript_01.js")); } } print("Hello, world");Franck SIMON Confoo 2012 - Java Scripting API 17 / 48
  • Communication entre Java etJavaScript ● Des objets Java peuvent être passés au script ● JavaScript peut alors utiliser les membres publiques des objets exposés ● void put(String key, Object value) passe un objet au moteur de script – méthode de ScriptEngine ● la méthode Object get(String key) permet à Java de récupérer des variable du script – méthode de ScriptEngineFranck SIMON Confoo 2012 - Java Scripting API 18 / 48
  • Utilisation dun objet Java parJavaScript ● Exemple UtilisationPoint_01.java public class UtilisationPoint_01 { public static void main(String[] args) throws FileNotFoundException, ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); Point p = new Point(1,2); engine.put("p1", p); engine.eval(new FileReader("point_01.js")); association pour utilisation } par JavaScript } var x = p1.getX(); var y = p1.getY(); print("le point se trouve en ("+x+","+y+")");Franck SIMON Confoo 2012 - Java Scripting API 19 / 48
  • Utilisation dun objet Java parJavaScript ● JavaScript peut donc changer létat de notre Point ● Exemple UtilisationPoint_02.java public class UtilisationPoint_02 { public static void main(String[] args) throws FileNotFoundException, ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); Point p = new Point(1,2); engine.put("p1", p); engine.eval(new FileReader("point_02.js")); System.out.println(p); } } p1.setX(110) ;Franck SIMON Confoo 2012 - Java Scripting API 20 / 48
  • Récupération de variables JavaScript ● Exemple RecuperationVariables_01.java public class RecuperationVariables_01 { public static void main(String[] args) throws FileNotFoundException, ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); engine.eval(new FileReader("variables_01.js")); String message = (String) engine.get("message"); System.out.println("message : "+message); double d = (Double) engine.get("dimension"); System.out.println("dimension : "+d); List<String> liste = (List<String>) engine.get("liste"); for(String ville : liste) System.out.println(ville); } } var message = "Hello, world"; var dimension = 10.3; var liste = ["Montréal","Saint-Malo","Paris"];Franck SIMON Confoo 2012 - Java Scripting API 21 / 48
  • Invoquer des fonctions JavaScript enJava ● Un des intérêts de dutiliser JavaScript dans un programme Java est dutiliser des fonctions JavaScript ● créées par dautres développeur ● ou des "utilisateurs avertis" ● valable aussi pour des objets JavaScriptFranck SIMON Confoo 2012 - Java Scripting API 22 / 48
  • Invoquer des fonctions JavaScript enJava ● Le moteur de script doit implémenter linterface Invocable de lAPI ● rhino implémente Invocable ● Permet linvocation depuis Java de fonctions du script ● ou méthodes dobjet JavaScript ● Permet au script dimplémenter des interfaces Java ● et là cela devient très intéressantFranck SIMON Confoo 2012 - Java Scripting API 23 / 48
  • Invoquer des fonctions JavaScript enJava ● Schéma de codage de linvocation de fonctions JavaScript en Java ● récupérer un ScriptEngine ● évaluer le script ● caster le ScriptEngine en Invocable ● appeler la méthode invokeFunction sur le Invocable – ou invokeMethod pour un objet JavaScript – une exception NoSuchMethodException est susceptible dêtre levéeFranck SIMON Confoo 2012 - Java Scripting API 24 / 48
  • Invoquer des fonctions JavaScript enJava ● Exemple InvoqueJavaScript_01.java public class InvoqueJavaScript_01 { public static void main(String[] args) throws FileNotFoundException, ScriptException, NoSuchMethodException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.eval(new FileReader("fonctions_01.js")); Invocable invocable = (Invocable) engine; double r = (Double) invocable.invokeFunction("somme", 10,20); System.out.println("Résulat r : "+r); } } function somme(i,j){ return i+j; }Franck SIMON Confoo 2012 - Java Scripting API 25 / 48
  • Invoquer des fonctions JavaScript enJava ● Invoquer une fonction JavaScript avec un nombre variable de paramètres ● Exemple InvoqueJavaScript_02.java ... engine.eval(new FileReader("fonctions_01.js")); Invocable invocable = (Invocable) engine; double r = (Double) invocable.invokeFunction("add", 10,20); System.out.println("Résulat r : "+r); ... function add(){ var res = 0; for(var i=0 ; i<arguments.length; i++){ res = res + arguments[i]; } return res; }Franck SIMON Confoo 2012 - Java Scripting API 26 / 48
  • Invoquer des méthodes dobjetsJavaScript en Java ● Exemples InvoqueJavaScript_03.java...engine.eval(new FileReader("fonctions_01.js"));Invocable invocable = (Invocable) engine;Object voiture = engine.get("voiture");invocable.invokeMethod(voiture, "rouler");invocable.invokeMethod(voiture, "atteindre", 130);System.out.println("Nb de chevaux : "+ invocable.invokeMethod(voiture, "getNbChevaux"));... var voiture = new Object(); voiture.getNbChevaux=function(){return 5;} voiture.rouler = function(){println(Je roule !!!!);} voiture.atteindre=function(vitesse){ println("Accélération jusquà "+vitesse+" km/h");}Franck SIMON Confoo 2012 - Java Scripting API 27 / 48
  • Implémenter des interfaces Java enJavaScript ● Les interfaces fournissent une couche abstraite ● Il peut être intéressant de sortir un traitement de la couche Java pour limplémenter en JavaScript ● code métier changeant ● Java fournit linterface et JavaScript limplémentation ● par des fonctions ● par des méthodes dobjetsFranck SIMON Confoo 2012 - Java Scripting API 28 / 48
  • Implémenter des interfaces Java enJavaScript ● Comme pour linvocation depuis Java de fonctions JavaScript, il faut que le moteur de script implémente Invocable ● La méthode getInterface renvoie une implémentation dune interface Java avec les fonctions trouvées par linterpréteurFranck SIMON Confoo 2012 - Java Scripting API 29 / 48
  • Implémenter des interfaces Java enJavaScript ● Linterface Calculable public interface Calculable { int add(int a, int b); } ● Limplémentation en JavaScript ● fichier implementations_01.js function add(a,b){ return a+b;}Franck SIMON Confoo 2012 - Java Scripting API 30 / 48
  • Implémenter des interfaces Java enJavaScript ● Lutilisation de limplémentation en Java ● fichier ImplementationJavaScript_01.java ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); engine.eval(new FileReader("implementations_01.js")); Invocable invocable = (Invocable) engine; Calculable calculable = invocable.getInterface(Calculable.class); System.out.println(calculable.add(10,20));Franck SIMON Confoo 2012 - Java Scripting API 31 / 48
  • Implémenter des interfaces Java enJavaScript ● Si limplémentation utilise un objet JavaScript il faut dabord le retrouver ● implémentation JavaScript – fichier implementations_01.js var calcul = new Object(); calcul.add = function(a,b){return a+b;} ● utilisation en Java – fichier ImplementationJavaScript_01.java engine.eval(new FileReader("implementations_01.js")); Invocable invocable = (Invocable) engine; Object obj = engine.get("calcul"); Calculable calculable = invocable.getInterface(obj,Calculable.class); System.out.println(calculable.add(10,20));Franck SIMON Confoo 2012 - Java Scripting API 32 / 48
  • Import Java dans JavaScript ● Par la fonction importPackage de JavaScript ● moteur rhino ● le nom du package correspond à son import entier – importPackage(java.util) ; ● correspond à un – import java.util.* ; ● java.lang nest pas importé par défaut ● Par la fonction importClass de JavaScript ● Attention les noms de packages doivent suivre la spécification JavaFranck SIMON Confoo 2012 - Java Scripting API 33 / 48
  • Import Java dans JavaScript ● Fichier JavaScript import_01.js importPackage(java.awt); var frame = new java.awt.Frame("Hello"); frame.setVisible(true); ● Exécution du fichier en Java public class EvalReaderImport_01 { public static void main(String[] args) throws ScriptException, FileNotFoundException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("javascript"); engine.eval(new FileReader("import_01.js")); } }Franck SIMON Confoo 2012 - Java Scripting API 34 / 48
  • Import Java dans JavaScript ● le moteur de script rhino propose aussi un JavaImporter ● fichier import_02.js var gui = new JavaImporter(java.awt); with(gui){ var frame = new Frame("Bonjour"); frame.setVisible(true); }Franck SIMON Confoo 2012 - Java Scripting API 35 / 48
  • Résolution de la surcharge ● Le langage Java supporte la surcharge par les arguments dune méthode ● signatures différentes dun même nom de méthode ● la résolution de lappel est alors effectuée lors de la compilation ● Lors de lappel de méthodes Java depuis un JavaScript le moteur sélectionne la méthode appropriée ● une exception est levée si aucune méthode nest trouvéeFranck SIMON Confoo 2012 - Java Scripting API 36 / 48
  • Utilisation de plusieurs contextes descript ● Dans le exemples précédents les objets Java ont étés exposés à JavaScript dans le contexte par défaut ● Deux contextes existent par défaut ● un contexte global partagé par tous les moteurs qui seront instanciés par le même EngineFactory – ScriptContext.GLOBAL_SCOPE ● un contexte par moteur de script – ScriptContext.ENGINE_SCOPEFranck SIMON Confoo 2012 - Java Scripting API 37 / 48
  • Utilisation de plusieurs contextes descript ● Exemple de manipulation de contexte public class MultiScope { public static void main(String[] args) throws ScriptException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine1 = factory.getEngineByName("javascript"); ScriptEngine engine2 = factory.getEngineByName("javascript"); ScriptContext context = new SimpleScriptContext(); Bindings globalScope = engine1.getBindings(ScriptContext.GLOBAL_SCOPE); String script = "println(x : +x)"; globalScope.put("x", "Bonjour"); … // suite page suivanteFranck SIMON Confoo 2012 - Java Scripting API 38 / 48
  • Utilisation de plusieurs contextes descript ● Exemple de manipulation de contexte … // cf. page précédente globalScope.put("x", "Bonjour"); engine1.eval(script); engine2.eval(script); System.out.println("======================"); engine1.put("x", "Hello"); engine1.eval(script); engine2.eval(script); System.out.println("======================"); engine1.eval(script,engine1.getBindings(ScriptContext.GLOBAL_SCOPE)); engine2.eval(script); } }Franck SIMON Confoo 2012 - Java Scripting API 39 / 48
  • Exemple du "monde réel"Et maintenant... … un peu de code pour grande personneFranck SIMON Confoo 2012 - Java Scripting API 40 / 48
  • Exemple : le pattern Visitor ● Lobjectif du modèle de conception Visitor est de séparer un modèle de données de ses traitements ● le modèle de données est souvent structuré en composite ● les traitements peuvent être enrichis sans modifier le modèle de données ● les données doivent "accepter" la visite dun "visiteur" ● cest le visiteur qui effectue le traitement en fonction du type concret de la donnéeFranck SIMON Confoo 2012 - Java Scripting API 41 / 48
  • Exemple : le pattern Visitor ● Ce modèle de conception est très utile si ● la structure des données est stable ● la structure de données est figée – les données et leurs traitements sont séparés – lévolution des traitements est indépendant des données ● Voici la structure extraite de louvrage du GoF ● Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides ● "Design Patterns – Elemnts of Reusable Object-Oriented Software" en 1995Franck SIMON Confoo 2012 - Java Scripting API 42 / 48
  • Exemple : le pattern Visitor ● Diagramme issu du livre du GoFFranck SIMON Confoo 2012 - Java Scripting API 43 / 48
  • Exemple : le pattern Visitor ● Le diagramme de notre exempleFranck SIMON Confoo 2012 - Java Scripting API 44 / 48
  • Exemple : le pattern Visitor ● Linterface Visitor et son implémentation en JavaScriptpublic interface Visitor { var visitor = new Object(); void visitText(Text t); visitor.visitText = function(objText){ void visitLine(Line l); println(objText.getText()); void visitPanel(Panel p); }} visitor.visitLine=function(objLine){ println(objLine.getLongueur()); } visitor.visitPanel=function(objPanel){ println(objPanel.getType()); var liste =objPanel.getElements(); for(var i=0 ; i < liste.size() ; i++){ liste.get(i).accept(visitor) } }Franck SIMON Confoo 2012 - Java Scripting API 45 / 48
  • Exemple : le pattern Visitor ● Mise en œuvre en Java...ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("javascript");engine.eval(new FileReader("visitors.js")); on récupère lobjet JavaScriptObject o = engine.get("visitor");Invocable invocable = (Invocable) engine;Visitor visitor = invocable.getInterface(o, Visitor.class);engine.put("visitor", visitor);p3.accept(visitor); Java voit lobjet JavaScript comme... implémentation de Visitor Pour que le moteur JavaScript puisse caster lobjet en VisitorFranck SIMON Confoo 2012 - Java Scripting API 46 / 48
  • Pour aller plus loin ● Web ● documentation officielle – http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html ● documentation mozilla – projet rhino –http://www.mozilla.org/rhino/ ● Livres ● Beginning Java SE 6 Platform – auteur : Jeff FRIESEN – éditeur : ApressFranck SIMON Confoo 2012 - Java Scripting API 47 / 48
  • Et voilà !!!Franck SIMON Confoo 2012 - Java Scripting API 48 / 48