2016-06-10 7 views
0

nashorn Ich habe eine skriptfähige Bohne wie untenein Rhino skript Bohne Migration

package test.rhino; 

import java.util.HashMap; 

import org.mozilla.javascript.Scriptable; 

public class SomeBean implements Scriptable { 

    /** 
    * The current values for this object. 
    */ 
    private HashMap<String, Object> values = new HashMap<>(); 

    /** 
    * 
    */ 
    public SomeBean() { 
     System.out.println("SomeBean();"); 
    } 

    /* 
    * @see org.mozilla.javascript.Scriptable#getClassName() 
    */ 
    @Override 
    public String getClassName() { 
     return "SomeBean"; 
    } 

    /* 
    * @see org.mozilla.javascript.Scriptable#get(java.lang.String, 
    * org.mozilla.javascript.Scriptable) 
    */ 
    @Override 
    public Object get(String name, Scriptable start) { 

     System.out.println("Get is called."); 
     System.out.println("Called for this" + name + " and returned :" + values.get(name)); 

     return values.get(name); 
    } 

    /* 
    * @see org.mozilla.javascript.Scriptable#put(java.lang.String, 
    * org.mozilla.javascript.Scriptable, java.lang.Object) 
    */ 
    @Override 
    public void put(String name, Scriptable start, Object value) { 
     System.out.println("Put is called. Input name: " + name + "\n Input values: " + value); 

     values.put(name, value); 

    } 

    @Override 
    public Object get(int index, Scriptable start) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public boolean has(String name, Scriptable start) { 
     // TODO Auto-generated method stub 
     return false; 
    } 

    @Override 
    public boolean has(int index, Scriptable start) { 
     // TODO Auto-generated method stub 
     return false; 
    } 

    @Override 
    public void put(int index, Scriptable start, Object value) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void delete(String name) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void delete(int index) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public Scriptable getPrototype() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public void setPrototype(Scriptable prototype) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public Scriptable getParentScope() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public void setParentScope(Scriptable parent) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public Object[] getIds() { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public Object getDefaultValue(Class<?> hint) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public boolean hasInstance(Scriptable instance) { 
     // TODO Auto-generated method stub 
     return false; 
    } 

} 

In Rhino gezeigt, mit Hilfe von Javascript ich die Schlüssel in den zugrunde liegenden HashMap als die Eigenschaften der Bohne zugreifen können.

var bean = new SomeBean();" 
       + "bean.nomen = 'John Doe';\n" 
       + "bean.nomen2 = bean.nomen + ' is cool'; 

Die Ausgabe zeigt, die erhalten und stellen die Schlüssel und Wert aufgerufen wird hinzugefügt und aus der ‚Werte‘ HashMap abgerufen. Auf diese Weise kann ich auch zusätzliche Funktionalität hinzufügen, um die Methodendefinition zu erhalten() und put().

Während ich diese Bean nach Nashorn portierte, konnte ich keinen Weg finden, dieselbe Funktionalität zu haben. Nashorn setzt die HashMap in Javascript frei und erlaubt es uns, Einträge hinzuzufügen, aber für mich sollte dieses Verhalten von der Bean-Instanz über einen gemeinsamen Setter oder Getter zugänglich sein, damit ich mehr Sachen machen kann, während Werte von der HashMap hinzugefügt und abgerufen werden.

So soll es wie unten arbeiten: -

Assume bean = new SomeBean(); 
bean.name = 'John Doe' // Adds name and John Doe to the HashMap 
print(bean.name) // Retrieves John Doe. 

Gibt es eine Möglichkeit, dies in Nashorn zu erreichen ?. Ich bin mir bewusst, dass öffentliche Klassenvariablen für meine Bean-Instanz verfügbar sind, aber das gibt mir nicht die gleiche Funktionalität wie oben gezeigt. Ich möchte auch nicht direkt auf die HashMap zugreifen.

Danke.

Antwort

1

Nach viel graben, war ich in der Lage, dies zu lösen, indem ich meine Bohne von 'AbstractJSObject' Klasse ausdehnte. Diese Klasse hatte Proxy-Methoden get, set und hat Methoden, die aufgerufen werden, wenn wir versuchen, mit einem Punktoperator auf die Objekteigenschaften zuzugreifen/sie zu ändern.

Die geänderte Klasse sieht wie folgt aus.

package test.nashorn; 

import java.util.HashMap; 

import jdk.nashorn.api.scripting.AbstractJSObject; 

public class NSomeOtherBean extends AbstractJSObject { 

    /** 
    * The current values for this object. 
    */ 
    private HashMap<String, Object> values = new HashMap<>(); 

    public NSomeOtherBean() { 
     System.out.println("Constructor called."); 
    } 

    // do you have a property of that given name? 
    @Override 
    public boolean hasMember(String name) { 
     return has(name); 
    } 

    // get the value of that named property 
    @Override 
    public Object getMember(String name) { 

     return get(name); 

    } 

    // get the value of that named property 
    @Override 
    public void setMember(String name,Object value) { 

     put(name,value); 

    } 

    public Object get(String name) { 

     System.out.println("JAVA Get is called."); 
     // System.out.println("Called for this"+name+" and returned 
     // :"+values.get(name)); 

     return values.get(name); 
    } 

    public void put(String name, Object value) { 
     System.out.println("JAVA Put is called. Input name: " + name + "\n Input values: " + value); 

     values.put(name, value); 

    } 

    public boolean has(String name) { 
     System.out.println("JAVA Has is called. Input name: " + name); 

     return values.containsKey(name); 

    } 
}