Login
Cerca all'interno di JavaPortal
Help
Home Page Documentazione Forum Progetti Partner Pubblica!
Documentazione > Tutorial > Controllo sintattico Javascript tramite l'interprete Java di BeanShell
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy

Hai una tesi in Java?
Tesine preparate
per esami?
Pubblica tutto su
JavaPortal!

Scrivi al nostro staff


I corsi elearning per la certificazione Sun gratuiti


Henry Ford
Vero progresso quando i vantaggi di una nuova tecnologia diventano per tutti


Hibernate:Oggetti a lunga conservazione


Rss Feed
Home Page
Articoli
News
Forum
Classi

  Visualizza Commenti (0) Aggiungi Commento    
Add to Shortcuts
 
Vota l'articolo
Controllo sintattico Javascript tramite l'interprete Java di BeanShell
By Francesco Mele
1 settembre 2005

  Controllo sintattico Javascript tramite l'interprete Java di BeanShell
Program Conclusioni

Valutare la correttezza sintattica di codice javascript usando un interprete java.
Tra gli esercizi più frequenti ed utili per un programmatore sicuramente troviamo la creazione di un interprete.

Un interprete, in informatica come nel linguaggio comune, non è altro che un "traduttore" da un linguaggio ad un altro. Per esempio ogni browser è dotato di un "traduttore" per il codice javascript in modo da leggere le funzioni e trasformarle in altre che il browser comprende, vale a dire in azioni a cui corrispondono animazioni, funzioni logiche/aritmetiche (somme, ecc..) in base a quanto richiesto dal programmatore che si è occupato di crearle.

I linguaggi interpretati hanno avuto molta fortuna in tempi recenti per la semplicità di utilizzo e la facilità nella scrittura. Non richiedono alcun compilatore perché direttamente letti (=interpretati).

Javascript è un ottimo esempio di linguaggio interpretato!

BeanShell è un interprete Java che permette l'esecuzione di codice Java.

La sua utilità è vastissima: per esempio permette di eseguire test di web application da remoto, eseguire codice java dinamicamente, creare applet per il porting su web di applicazioni già esistenti, …

In questo articolo non useremo BeanShell per il suo utilizzo “classico”, ma descriveremo un primo passo per poter utilizzare il suo interprete per validare codice javascript.

Una valutazione per BeanShell si presenta nel seguente formato:

      Interpreter interpreter = new Interpreter();

       interpreter.eval("System.out.println(\"Hello world!\")");

Il risultato non lancia eccezioni, dovute ad errori sintattici, e fornisce in console il solito:

      Hello world!

Per utilizzare un interprete Java per javascript dobbiamo fargli credere di valutare codice Java.

Dobbiamo allora realizzare un mapping tra i due linguaggi. Lo scopo è trasformare il codice javascript in codice java, l'unico compreso dall'interprete che poi lo valuterà e ci dirà se è corretto.

Per raggiungere il nostro obiettivo innanzitutto occorre evidenziare le differenze e le analogie sintattiche tra java e javascript.

Javascript non è un linguaggio strettamente tipizzato. Per Java esiste un oggetto dal quale tutti derivano (e questo ci tornerà comodo più avanti): Object. Fanno eccezione i tipi primitivi (int, ecc...) per i quali si possono utilizzare le corrispondenti classi wrapper (Integer, ecc...).

Entrambi i linguaggi utilizzano un paradigma ad oggetti. In javascript alcuni di questi sono impliciti, cioé non è necessario dichiararli perché esiste sempre una istanza nel browser: per esempio per "window" non occorre scrivere var window = new Window();.

La sintassi è molto simile: cicli, assegnamenti e tutte le istruzioni base sono equivalenti.

Analizziamo un semplice esempio di codice javascript:

for(i=0; i<9; i++){

      alert("ciclo n° "+i);

}

 

L'analogo in java è:

for(i=0; i<9; i++){

      System.out.println("ciclo n° "+i);

}

Prima di tutto quindi occorre sostituire "alert" con "System.out.println".

Allo stesso modo dobbiamo sostituire altre funzioni: confirm, ecc...

/**
* javascript2java
* replacing javascript code with corresponding java code
* <b>incomplete</b>
* */

public static String javascript2java(String javascriptCode){

      // sostituisco tutte le occorrenze di alert con System.out.println

      javascriptCode = replace(javascriptCode, " alert(", "System.out.println(\"\"+");

      // sostituisco var con Object

      javascriptCode = replace(javascriptCode, " var ", " Object ");

      return javascriptCode;

}// --- javascript2java

 

(il metodo replace sostituisce ricorsivamente parti di testo)

Come si può notare oltre a sostituire l'alert operiamo un'altra importante sostituzione.

In javascript si usa un solo modo per dichiarare una variabile: "var".

Per fortuna tutte le classi in java sono anche Object!

Il mapping var - Object è quindi immediato.

Rimangono da tradurre in java gli oggetti impliciti.

Partiamo da un esempio javascript:

var str2write = "<b>nuova stringa</b>";

document.write(str2write);

Se vogliamo che l'interprete non produca errore dobbiamo dargli la possibilità di "trovare" la risorsa document e fare in modo che sia dotata di un metodo statico write(Object).

Per essere sicuri che trovi ogni risorsa utile, non potendo passare il nome completo della classe, dovremo creare la classe document nel "default package":

public class document {

      public static void write(Object s){

      //empty method

      }

}// ------------------------------------- end

 

per poter poi invocare il metodo write direttamente, questo deve essere statico.
Allo stesso modo dobbiamo muoverci per la classe window.
Notiamo però subito un aspetto fondamentale di javascript.

Una finestra può essere chiamata in diversi modi, tutte istanze della Window corrente:

le chiamate

      window.close();

       self.close();

producono lo stesso effetto!

Anche l'opener (la finestra che ha eseguito una window.open("")) è una istanza di una window!

Ne consegue una tassonomia di classi, tutte con le stesse caratteristiche. L'ereditarietà disponibile in java ci viene incontro.

/**
* @author Francesco Mele
* Created on Aug 17, 2004
*
* simulating javascript window object and its method and properties
*/

public class window {

      public static document document;

      public static Object open(Object o){

      return o;

      }

      public static void close(){

      //empty method

      }

}// --------------------------------------------- end

 

e

 

/**
* @author Francesco Mele
* Created on Aug 17, 2004
*
* self is a window
*/

public class self extends window {

}// ---------------------------------------- end

 

/**
* @author Francesco Mele
* Created on Aug 17, 2004
*
* opener is a window
*/

public class opener extends window {

}// ------------------------------------ end

 

 

In questo modo invocando la open su una classe self verrà chiamata la open della classe padre.

Passiamo finalmente a valutare un po' di codice javascript.

Il metodo della nostra classe Evaluator è

 

/**
* eval
* just calls the eval method of interpreter
* @see bsh.Interpreter
* @return true if no errors occurr
* */

public static boolean eval(String strToCheck){

      Interpreter interpreter = new Interpreter();

      try {

            interpreter.eval(strToCheck);

      } catch (EvalError e) {

            System.err.println("// -------------------------- //\n" +

            "// ---> error is:\n"+e.getMessage()+

            "\n// -------------------------- //");

            return false;

      }

      return true;

}// --- eval

 

dove ritroviamo la chiamata all'eval di BeanShell vista in precedenza.

Il nostro main è quindi

public static void main(String[] args) {

      String str2check = "";

      //str2check += "alert(\"start\"); for (i=0; i<9; i++) { var txt = \"this is a text\"; document.write(i+\":       \"+txt);} alert(\"end\"); ";

      str2check += "location.href(\"http://....\")";

      String str2code = Js2JavaUtils.javascript2java(str2check);

      if (eval(str2code)){

            System.out.println("No errors occurred");

      }else {

            System.err.println("Failing checking java code!");

      }

}// --- main

 

Ho lasciato anche un paio di semplici test; basta decommentare.

NOTA

L'interprete esegue il codice java risultante, quindi un System.out.println produrrà una riga in console.

Nella classe Evaluator ho anche riportato un estratto di codice trovato in rete con il quale potersi divertire nell'uso dell'interprete BeanShell. Provate a far valutare espressioni aritmetiche del tipo

a = 3*2

oppure

a = 3*2 == 6



Conclusioni top

Quello che abbiamo realizzato in questo articolo è solo un primo passo perché javascript è un linguaggio che può assumere forme molto complicate (utilizzo di oggetti complessi, creazione di nuovi oggetti custom, la possibilità di estendere oggetti già esistenti, ecc...) per cui il mapping non è sempre così semplice.

Un esempio per tutti.

In java possiamo scrivere:

Object foo = "questo è anche un oggetto";

ma NON:

Object foo = 1;

questo perché 1 è un tipo primitivo. Ne risulta che non possiamo ri-scrivere "var intero = 1;" in " Object intero = 1;" come visto finora.

Ancora più semplicemente, in javascript possiamo dimenticarci qualche ";", in java no!

Nonostante le limitazioni espresse, quanto appena visto è un ottimo esercizio per prendere familiarità con BeanShell le cui potenzialità di certo non si fermano qui.

Se invece nella nostra applicazione web facciamo uso di semplice codice javascript generato automaticamente, possiamo anche validarlo utilizzando quanto appena visto.

Inoltre per completare il mapping per il controllo della sintassi per le funzioni più semplici non manca tantissimo.

Scarica Il file sorgente JsChecker.zip



 Attachments List
Generic DocumentJsChecker.zip
Username:
Password:
To sign up for an account, click register... Register
Hide





Powered By



Campagna Anti-IF


Skin


PARTNER
Zio Budda
HostingJava


LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is domenica 1 agosto 2010